Files
tutti/tools/scripts/all-process-time-profile.mjs
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

87 lines
2.4 KiB
JavaScript

import { spawn } from "node:child_process";
import { setTimeout as delay } from "node:timers/promises";
const readyPattern = /Ctrl-C to stop the recording/iu;
export function buildAllProcessTimeProfileArgs(outputPath) {
return [
"xctrace",
"record",
"--template",
"Time Profiler",
"--all-processes",
"--no-prompt",
"--output",
outputPath
];
}
export async function startAllProcessTimeProfile(input) {
if (process.platform !== "darwin") {
throw new Error("all-process Time Profiler capture requires macOS");
}
const child = spawn(
"xcrun",
buildAllProcessTimeProfileArgs(input.outputPath),
{
cwd: input.cwd,
env: process.env,
stdio: ["ignore", "pipe", "pipe"]
}
);
let output = "";
const append = (chunk) => {
output = (output + chunk.toString()).slice(-20_000);
};
child.stdout.on("data", append);
child.stderr.on("data", append);
let exitResult = null;
const exit = new Promise((resolveExit) => {
child.once("error", (error) => {
exitResult = { error };
resolveExit(exitResult);
});
child.once("exit", (code, signal) => {
exitResult = { code, signal };
resolveExit(exitResult);
});
});
const deadline = Date.now() + (input.timeoutMs ?? 30_000);
while (!readyPattern.test(output)) {
if (exitResult) {
throw new Error(
`xctrace exited before recording (${exitResult.error?.message ?? exitResult.code ?? exitResult.signal ?? "unknown"})${output.trim() ? `: ${output.trim()}` : ""}`
);
}
if (Date.now() >= deadline) {
child.kill("SIGKILL");
await exit;
throw new Error(
`timed out waiting for xctrace Time Profiler${output.trim() ? `: ${output.trim()}` : ""}`
);
}
await delay(100);
}
let stopped = false;
return {
outputPath: input.outputPath,
async stop() {
if (stopped) return;
stopped = true;
child.kill("SIGINT");
const result = await Promise.race([exit, delay(45_000).then(() => null)]);
if (!result) {
child.kill("SIGKILL");
await exit;
throw new Error("timed out saving xctrace Time Profiler capture");
}
if (result.code !== 0) {
throw new Error(
`xctrace failed (${result.error?.message ?? result.code ?? result.signal ?? "unknown"})${output.trim() ? `: ${output.trim()}` : ""}`
);
}
}
};
}