源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
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
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
This commit is contained in:
commit
2ed3415fb7
8018 files changed
+1936476
No files matched your search
@@ -0,0 +1,114 @@
|
||||
import { spawn } from "node:child_process";
|
||||
import { access, mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { isAbsolute, join, resolve } from "node:path";
|
||||
|
||||
const projectRootEnvironment = "TUTTI_AGENT_SESSION_REPLAY_PROJECT_ROOT";
|
||||
const temporaryProjectPrefix = "tutti-agent-session-rec-";
|
||||
|
||||
export function resolveAgentSessionReplayProjectRoot() {
|
||||
const fromEnvironment = process.env[projectRootEnvironment]?.trim();
|
||||
if (fromEnvironment) {
|
||||
if (!isAbsolute(fromEnvironment)) {
|
||||
throw new Error(`${projectRootEnvironment} must be an absolute path`);
|
||||
}
|
||||
return resolve(fromEnvironment);
|
||||
}
|
||||
// Pure helpers may resolve portable paths before the CLI acquires its
|
||||
// run-scoped project. Keep that fallback outside the product checkout.
|
||||
return join(tmpdir(), "tutti-agent-session-rec", `unbound-${process.pid}`);
|
||||
}
|
||||
|
||||
export async function acquireAgentSessionReplayProjectRoot({
|
||||
keepRuntime = false
|
||||
} = {}) {
|
||||
const previous = process.env[projectRootEnvironment];
|
||||
if (previous?.trim()) {
|
||||
const root = resolveAgentSessionReplayProjectRoot();
|
||||
await mkdir(root, { recursive: true });
|
||||
return {
|
||||
owned: false,
|
||||
root,
|
||||
async dispose() {}
|
||||
};
|
||||
}
|
||||
|
||||
const root = await mkdtemp(join(tmpdir(), temporaryProjectPrefix));
|
||||
try {
|
||||
await initializeTemporaryProject(root);
|
||||
} catch (error) {
|
||||
await rm(root, { force: true, recursive: true });
|
||||
throw error;
|
||||
}
|
||||
process.env[projectRootEnvironment] = root;
|
||||
let disposed = false;
|
||||
return {
|
||||
owned: true,
|
||||
root,
|
||||
async dispose() {
|
||||
if (disposed) return;
|
||||
disposed = true;
|
||||
if (previous === undefined) {
|
||||
delete process.env[projectRootEnvironment];
|
||||
} else {
|
||||
process.env[projectRootEnvironment] = previous;
|
||||
}
|
||||
if (!keepRuntime) {
|
||||
await rm(root, { force: true, recursive: true });
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function initializeTemporaryProject(root) {
|
||||
await runGit(root, ["init", "--quiet"]);
|
||||
await writeFile(
|
||||
join(root, "README.md"),
|
||||
[
|
||||
"# Tutti session-replay temporary project",
|
||||
"",
|
||||
"This run-scoped project is intentionally outside the product checkout.",
|
||||
""
|
||||
].join("\n")
|
||||
);
|
||||
await runGit(root, ["add", "README.md"]);
|
||||
await runGit(root, [
|
||||
"-c",
|
||||
"user.name=Tutti Session Replay",
|
||||
"-c",
|
||||
"user.email=session-replay@tutti.invalid",
|
||||
"commit",
|
||||
"--quiet",
|
||||
"-m",
|
||||
"chore: initialize session-replay project"
|
||||
]);
|
||||
await access(join(root, ".git"));
|
||||
}
|
||||
|
||||
function runGit(cwd, args) {
|
||||
return new Promise((resolveRun, rejectRun) => {
|
||||
const child = spawn("git", args, {
|
||||
cwd,
|
||||
env: process.env,
|
||||
stdio: ["ignore", "ignore", "pipe"]
|
||||
});
|
||||
let stderr = "";
|
||||
child.stderr.on("data", (chunk) => {
|
||||
stderr += chunk.toString();
|
||||
});
|
||||
child.once("error", rejectRun);
|
||||
child.once("exit", (code, signal) => {
|
||||
if (code === 0) {
|
||||
resolveRun();
|
||||
return;
|
||||
}
|
||||
rejectRun(
|
||||
new Error(
|
||||
`git ${args.join(" ")} failed (${code ?? signal ?? "unknown"})${
|
||||
stderr.trim() ? `: ${stderr.trim()}` : ""
|
||||
}`
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user