forked from Piebald-AI/tweakcc
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnativeInstallationLoader.ts
More file actions
106 lines (96 loc) · 3.39 KB
/
Copy pathnativeInstallationLoader.ts
File metadata and controls
106 lines (96 loc) · 3.39 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
/**
* Helper module for dynamically loading nativeInstallation.ts.
*
* nativeInstallation.ts depends on node-lief, which may not be available on all systems
* (e.g., NixOS or systems without proper C++ libraries). This module provides a safe way
* to dynamically import nativeInstallation.ts only when node-lief is available.
*/
import type {
extractClaudeJsFromNativeInstallation as ExtractFn,
repackNativeInstallation as RepackFn,
resolveNixBinaryWrapper as ResolveNixFn,
} from './nativeInstallation';
import { debug } from './utils';
interface NativeInstallationModule {
extractClaudeJsFromNativeInstallation: typeof ExtractFn;
repackNativeInstallation: typeof RepackFn;
resolveNixBinaryWrapper: typeof ResolveNixFn;
}
let cachedModule: NativeInstallationModule | null = null;
let loadError: string | null = null;
/**
* Attempts to load the nativeInstallation module.
* Returns null if node-lief is not available.
*/
async function tryLoadNativeInstallationModule(): Promise<NativeInstallationModule | null> {
if (cachedModule !== null) {
return cachedModule;
}
try {
// First check if node-lief is available
await import('node-lief');
// If it is, dynamically import the module that uses it
cachedModule = await import('./nativeInstallation');
loadError = null;
return cachedModule;
} catch (err) {
loadError = err instanceof Error ? err.message : String(err);
debug(`Error loading native installation module: ${loadError}`);
if (err instanceof Error) {
debug(err);
}
// node-lief not available
return null;
}
}
/** Returns the reason node-lief failed to load, or null if it loaded successfully. */
export function getNativeModuleLoadError(): string | null {
return loadError;
}
/**
* Extracts claude.js from a native installation binary.
* Returns null if node-lief is not available or extraction fails.
*/
export async function extractClaudeJsFromNativeInstallation(
nativeInstallationPath: string
): Promise<Buffer | null> {
const mod = await tryLoadNativeInstallationModule();
if (!mod) {
return null;
}
return mod.extractClaudeJsFromNativeInstallation(nativeInstallationPath);
}
/**
* Repacks a modified claude.js back into the native installation binary.
* This should only be called after a successful extractClaudeJsFromNativeInstallation(),
* which ensures the module is already loaded and cached.
*/
export async function repackNativeInstallation(
binPath: string,
modifiedClaudeJs: Buffer,
outputPath: string
): Promise<void> {
// The module should already be cached from a prior extractClaudeJsFromNativeInstallation() call
const mod = await tryLoadNativeInstallationModule();
if (!mod) {
throw new Error(
'`repackNativeInstallation()` called but `node-lief` is not available. ' +
'This is unexpected - `extractClaudeJsFromNativeInstallation()` should have been called first.'
);
}
mod.repackNativeInstallation(binPath, modifiedClaudeJs, outputPath);
}
/**
* Detects whether a binary is a Nix `makeBinaryWrapper` wrapper and returns
* the path to the real wrapped executable, or null if not a wrapper.
* Returns null if node-lief is not available.
*/
export async function resolveNixBinaryWrapper(
binaryPath: string
): Promise<string | null> {
const mod = await tryLoadNativeInstallationModule();
if (!mod) {
return null;
}
return mod.resolveNixBinaryWrapper(binaryPath);
}