refactor: reduce approval context overhead
CI / Client installer (macos-latest) (push) Canceled after 0s
CI / Client installer (ubuntu-latest) (push) Canceled after 0s
CI / Client installer (windows-latest) (push) Canceled after 0s
CI / test (22) (push) Canceled after 0s
CI / test (24) (push) Canceled after 0s
CI / release-smoke (push) Canceled after 0s
CI / Client installer (macos-latest) (push) Canceled after 0s
CI / Client installer (ubuntu-latest) (push) Canceled after 0s
CI / Client installer (windows-latest) (push) Canceled after 0s
CI / test (22) (push) Canceled after 0s
CI / test (24) (push) Canceled after 0s
CI / release-smoke (push) Canceled after 0s
This commit is contained in:
+24
-3
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
import { createHash, createPublicKey, randomUUID, verify as verifySignature } from "node:crypto";
|
||||
import {
|
||||
chmodSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readlinkSync,
|
||||
chmodSync, cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readlinkSync,
|
||||
readdirSync, realpathSync, renameSync, rmSync, unlinkSync, writeFileSync,
|
||||
} from "node:fs";
|
||||
import { homedir, tmpdir } from "node:os";
|
||||
@@ -301,8 +301,7 @@ async function installClient(paths: ClientPaths, args: ParsedArgs, context: Comm
|
||||
}
|
||||
renameSync(staging, versionDir);
|
||||
}
|
||||
mkdirPrivate(paths.skillDir);
|
||||
writeAtomic(paths.skillFile, skillBody, 0o600);
|
||||
installBundledSkill(paths, join(versionDir, "node_modules", "dingtalk-approval-client", "skill", "dingtalk-approval"), skillBody);
|
||||
writeAtomic(paths.publicKeyFile, publicArtifact, 0o600);
|
||||
writeLaunchers(paths, context.platform);
|
||||
const state: ClientInstallState = {
|
||||
@@ -590,6 +589,28 @@ function mcpConfig(paths: ClientPaths): Record<string, unknown> {
|
||||
return { mcpServers: { "dingtalk-approval": { type: "stdio", command: paths.bridgeCommand, args: [] } } };
|
||||
}
|
||||
|
||||
function installBundledSkill(paths: ClientPaths, bundledSkillDir: string, skillBody: Buffer): void {
|
||||
const reference = join(bundledSkillDir, "references", "create-approval.md");
|
||||
if (!existsSync(join(bundledSkillDir, "SKILL.md")) || !existsSync(reference)) {
|
||||
throw new Error("客户端包缺少完整 Skill 资源");
|
||||
}
|
||||
const parent = dirname(paths.skillDir);
|
||||
mkdirPrivate(parent);
|
||||
const staging = join(parent, `.dingtalk-approval.staging-${process.pid}-${randomUUID()}`);
|
||||
const backup = join(parent, `.dingtalk-approval.backup-${process.pid}-${randomUUID()}`);
|
||||
try {
|
||||
cpSync(bundledSkillDir, staging, { recursive: true });
|
||||
writeAtomic(join(staging, "SKILL.md"), skillBody, 0o600);
|
||||
if (existsSync(paths.skillDir)) renameSync(paths.skillDir, backup);
|
||||
renameSync(staging, paths.skillDir);
|
||||
if (existsSync(backup)) rmSync(backup, { recursive: true, force: true });
|
||||
} catch (error) {
|
||||
if (!existsSync(paths.skillDir) && existsSync(backup)) renameSync(backup, paths.skillDir);
|
||||
if (existsSync(staging)) rmSync(staging, { recursive: true, force: true });
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function writeLaunchers(paths: ClientPaths, platform: NodeJS.Platform): void {
|
||||
mkdirPrivate(paths.binDir);
|
||||
const launcher = `#!/usr/bin/env node\nimport { readFileSync } from "node:fs";\nimport { dirname, join, resolve } from "node:path";\nimport { fileURLToPath } from "node:url";\nimport { spawn } from "node:child_process";\nconst mode = process.argv[2];\nconst root = resolve(dirname(fileURLToPath(import.meta.url)), "..");\nconst state = JSON.parse(readFileSync(join(root, "install-state.json"), "utf8"));\nconst runtime = resolve(root, state.runtimeDir);\nconst target = join(runtime, "node_modules", "dingtalk-approval-client", "dist", "src", mode === "bridge" ? "bridge.js" : "client-installer.js");\nconst args = mode === "bridge" ? ["--url", state.gatewayUrl, ...process.argv.slice(3)] : [...process.argv.slice(3), "--app-root", root];\nconst env = mode === "bridge" ? { ...process.env, DINGTALK_APPROVAL_BRIDGE_STATE: join(root, "state", "session.json") } : process.env;\nconst child = spawn(process.execPath, [target, ...args], { stdio: "inherit", env });\nchild.on("exit", (code, signal) => { if (signal) process.kill(process.pid, signal); else process.exitCode = code ?? 1; });\nchild.on("error", (error) => { console.error(error.message); process.exitCode = 1; });\n`;
|
||||
|
||||
Reference in New Issue
Block a user