forked from ultraworkers/claw-code
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrawRead.ts
More file actions
130 lines (119 loc) · 4.08 KB
/
Copy pathrawRead.ts
File metadata and controls
130 lines (119 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* Minimal module for firing MDM subprocess reads without blocking the event loop.
* Has minimal imports — only child_process, fs, and mdmConstants (which only imports os).
*
* Two usage patterns:
* 1. Startup: startMdmRawRead() fires at main.tsx module evaluation, results consumed later via getMdmRawReadPromise()
* 2. Poll/fallback: fireRawRead() creates a fresh read on demand (used by changeDetector and SDK entrypoint)
*
* Raw stdout is consumed by mdmSettings.ts via consumeRawReadResult().
*/
import { execFile } from 'child_process'
import { existsSync } from 'fs'
import {
getMacOSPlistPaths,
MDM_SUBPROCESS_TIMEOUT_MS,
PLUTIL_ARGS_PREFIX,
PLUTIL_PATH,
WINDOWS_REGISTRY_KEY_PATH_HKCU,
WINDOWS_REGISTRY_KEY_PATH_HKLM,
WINDOWS_REGISTRY_VALUE_NAME,
} from './constants.js'
export type RawReadResult = {
plistStdouts: Array<{ stdout: string; label: string }> | null
hklmStdout: string | null
hkcuStdout: string | null
}
let rawReadPromise: Promise<RawReadResult> | null = null
function execFilePromise(
cmd: string,
args: string[],
): Promise<{ stdout: string; code: number | null }> {
return new Promise(resolve => {
execFile(
cmd,
args,
{ encoding: 'utf-8', timeout: MDM_SUBPROCESS_TIMEOUT_MS },
(err, stdout) => {
// biome-ignore lint/nursery/noFloatingPromises: resolve() is not a floating promise
resolve({ stdout: stdout ?? '', code: err ? 1 : 0 })
},
)
})
}
/**
* Fire fresh subprocess reads for MDM settings and return raw stdout.
* On macOS: spawns plutil for each plist path in parallel, picks first winner.
* On Windows: spawns reg query for HKLM and HKCU in parallel.
* On Linux: returns empty (no MDM equivalent).
*/
export function fireRawRead(): Promise<RawReadResult> {
return (async (): Promise<RawReadResult> => {
if (process.platform === 'darwin') {
const plistPaths = getMacOSPlistPaths()
const allResults = await Promise.all(
plistPaths.map(async ({ path, label }) => {
// Fast-path: skip the plutil subprocess if the plist file does not
// exist. Spawning plutil takes ~5ms even for an immediate ENOENT,
// and non-MDM machines never have these files.
// Uses synchronous existsSync to preserve the spawn-during-imports
// invariant: execFilePromise must be the first await so plutil
// spawns before the event loop polls (see main.tsx:3-4).
if (!existsSync(path)) {
return { stdout: '', label, ok: false }
}
const { stdout, code } = await execFilePromise(PLUTIL_PATH, [
...PLUTIL_ARGS_PREFIX,
path,
])
return { stdout, label, ok: code === 0 && !!stdout }
}),
)
// First source wins (array is in priority order)
const winner = allResults.find(r => r.ok)
return {
plistStdouts: winner
? [{ stdout: winner.stdout, label: winner.label }]
: [],
hklmStdout: null,
hkcuStdout: null,
}
}
if (process.platform === 'win32') {
const [hklm, hkcu] = await Promise.all([
execFilePromise('reg', [
'query',
WINDOWS_REGISTRY_KEY_PATH_HKLM,
'/v',
WINDOWS_REGISTRY_VALUE_NAME,
]),
execFilePromise('reg', [
'query',
WINDOWS_REGISTRY_KEY_PATH_HKCU,
'/v',
WINDOWS_REGISTRY_VALUE_NAME,
]),
])
return {
plistStdouts: null,
hklmStdout: hklm.code === 0 ? hklm.stdout : null,
hkcuStdout: hkcu.code === 0 ? hkcu.stdout : null,
}
}
return { plistStdouts: null, hklmStdout: null, hkcuStdout: null }
})()
}
/**
* Fire raw subprocess reads once for startup. Called at main.tsx module evaluation.
* Results are consumed via getMdmRawReadPromise().
*/
export function startMdmRawRead(): void {
if (rawReadPromise) return
rawReadPromise = fireRawRead()
}
/**
* Get the startup promise. Returns null if startMdmRawRead() wasn't called.
*/
export function getMdmRawReadPromise(): Promise<RawReadResult> | null {
return rawReadPromise
}