1import * as Effect from "effect/Effect";
2import * as FileSystem from "effect/FileSystem";
3import * as Path from "effect/Path";
4import * as Schema from "effect/Schema";
5
6const isNativeSessionId = Schema.is(Schema.String.check(Schema.isUUID(4)));
7const decodeSessionMetadata = Schema.decodeEffect(
8 Schema.fromJsonString(Schema.Struct({ cwd: Schema.String })),
9);
10
11/** Call after the process closes. The unique temporary cwd proves which session we own. */
12export const removeAntigravitySessionFiles = Effect.fn("removeAntigravitySessionFiles")(
13 function* (input: {
14 readonly profileDirectory: string;
15 readonly sessionId: string | undefined;
16 readonly cwd: string;
17 }) {
18 if (input.sessionId === undefined || !isNativeSessionId(input.sessionId)) {
19 return;
20 }
21 const fs = yield* FileSystem.FileSystem;
22 const path = yield* Path.Path;
23 const acpDirectory = path.join(input.profileDirectory, "antigravity-acp");
24 const base = path.join(acpDirectory, "conversations", input.sessionId);
25 if (!(yield* fs.exists(`${base}.meta`))) {
26 return;
27 }
28 const metadata = yield* fs
29 .readFileString(`${base}.meta`)
30 .pipe(Effect.flatMap(decodeSessionMetadata));
31 if (metadata.cwd !== input.cwd) {
32 return;
33 }
34 for (const suffix of [".db", ".db-wal", ".db-shm", ".db-journal", ".meta"]) {
35 yield* fs.remove(`${base}${suffix}`, { force: true });
36 }
37 yield* fs.remove(path.join(acpDirectory, "brain", input.sessionId), {
38 recursive: true,
39 force: true,
40 });
41 },
42 Effect.catch(() => Effect.logWarning("Could not remove temporary Antigravity session files.")),
43);
44
45/**
46 * Removes every per-process runtime temp directory under an instance's root.
47 * Call once when the driver starts, before it launches any process, so a
48 * previous server that was killed mid-session cannot leave unpacked runtimes
49 * behind. Only T3-owned directories are touched. The system temp directory
50 * belongs to other programs and Windows does not lock data files, so sweeping
51 * it could gut a live extraction.
52 */
53export const removeAntigravityRuntimeTempDirs = Effect.fn("removeAntigravityRuntimeTempDirs")(
54 function* (tempDirectory: string) {
55 const fs = yield* FileSystem.FileSystem;
56 yield* fs.remove(tempDirectory, { recursive: true, force: true });
57 },
58 Effect.catch(() =>
59 Effect.logWarning("Could not remove leftover Antigravity runtime temp files."),
60 ),
61);