返回 DeepSeek-Reasonix
shellLifecycle.ts
根目录 / desktop / electron / src / main / shellLifecycle.ts
1 import { randomUUID } from "node:crypto";
2 import { mkdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
3 import { dirname, join } from "node:path";
4 import type { HelloResult } from "./handshake.js";
5
6 type ShellBuild = { version: string; channel: string; commit: string };
7
8 export class ShellLifecycle {
9 private path = "";
10 private state: Record<string, unknown> | null = null;
11
12 constructor(
13 private readonly dataHome: string,
14 private readonly build: ShellBuild,
15 private readonly now = () => new Date(),
16 ) {}
17
18 start(hello: HelloResult): void {
19 if (!hello.diagnosticsEnabled || this.path) return;
20 const runId = randomUUID().replaceAll("-", "");
21 const at = this.now().toISOString();
22 this.path = join(this.dataHome, "diagnostics", "lifecycle", `shell-${process.pid}-${runId}.json`);
23 this.state = {
24 schemaVersion: 3,
25 pid: process.pid,
26 runId,
27 incidentId: hello.incidentId,
28 version: this.build.version,
29 buildCommit: this.build.commit,
30 channel: this.build.channel,
31 processRole: "shell",
32 phase: "healthy",
33 startedAt: at,
34 updatedAt: at,
35 };
36 this.write();
37 }
38
39 mark(phase: string): void {
40 if (!this.state || !phase) return;
41 this.state.phase = phase;
42 this.state.updatedAt = this.now().toISOString();
43 this.write();
44 }
45
46 complete(): void {
47 if (!this.path) return;
48 rmSync(this.path, { force: true });
49 this.path = "";
50 this.state = null;
51 }
52
53 private write(): void {
54 if (!this.path || !this.state) return;
55 mkdirSync(dirname(this.path), { recursive: true, mode: 0o700 });
56 const temporary = `${this.path}.tmp-${process.pid}`;
57 writeFileSync(temporary, `${JSON.stringify(this.state)}\n`, {
58 mode: 0o600,
59 });
60 renameSync(temporary, this.path);
61 }
62 }
63
63 lines TYPESCRIPT