blun-king-cli 9.1.626 → 9.1.628
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/core-bootstrap.js +93 -92
- package/bin/launcher-mode.js +126 -93
- package/bin/launcher-runtime.js +73 -8
- package/bin/managed-plugin-selection.cjs +116 -115
- package/bin/native-command-runner.js +72 -0
- package/bin/native-module-repair.js +26 -20
- package/bin/plugin-bootstrap.js +163 -162
- package/bin/rename-private-staging.cjs +82 -0
- package/blun.mjs +371 -527
- package/package.json +1 -1
- package/worker-host.mjs +2 -2
package/bin/core-bootstrap.js
CHANGED
|
@@ -1,92 +1,93 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const fs = require('node:fs');
|
|
4
|
-
const path = require('node:path');
|
|
5
|
-
const { pathToFileURL } = require('node:url');
|
|
6
|
-
|
|
7
|
-
const { acquireSharedRuntimeLease } = require('./update-lease');
|
|
8
|
-
const { installWindowsNodeCrashDump } = require('./windows-node-crash-dump.cjs');
|
|
9
|
-
const { recordRuntimeExit } = require('./runtime-exit-ledger.cjs');
|
|
10
|
-
const { isStandaloneHelpRequest } = require('./launcher-mode');
|
|
11
|
-
|
|
12
|
-
const CORE_LOADED_MESSAGE = 'blun-core-bootstrap-loaded';
|
|
13
|
-
|
|
14
|
-
function bindInteractiveTerminalOwner() {
|
|
15
|
-
if (process.platform !== 'win32' || process.env.BLUN_TERMINAL_OWNER !== '1' || !process.channel) return;
|
|
16
|
-
const stop = () => {
|
|
17
|
-
setTimeout(() => process.exit(143), 5000).unref();
|
|
18
|
-
if (!process.emit('SIGTERM')) process.exit(143);
|
|
19
|
-
};
|
|
20
|
-
process.once('disconnect', stop);
|
|
21
|
-
if (!process.connected) stop();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async function runCoreBootstrap() {
|
|
25
|
-
bindInteractiveTerminalOwner();
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
leaseResult.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
try {
|
|
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
|
-
process.
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { pathToFileURL } = require('node:url');
|
|
6
|
+
|
|
7
|
+
const { acquireSharedRuntimeLease } = require('./update-lease');
|
|
8
|
+
const { installWindowsNodeCrashDump } = require('./windows-node-crash-dump.cjs');
|
|
9
|
+
const { recordRuntimeExit } = require('./runtime-exit-ledger.cjs');
|
|
10
|
+
const { isStandaloneHelpRequest, isReadOnlyInspectionRequest } = require('./launcher-mode');
|
|
11
|
+
|
|
12
|
+
const CORE_LOADED_MESSAGE = 'blun-core-bootstrap-loaded';
|
|
13
|
+
|
|
14
|
+
function bindInteractiveTerminalOwner() {
|
|
15
|
+
if (process.platform !== 'win32' || process.env.BLUN_TERMINAL_OWNER !== '1' || !process.channel) return;
|
|
16
|
+
const stop = () => {
|
|
17
|
+
setTimeout(() => process.exit(143), 5000).unref();
|
|
18
|
+
if (!process.emit('SIGTERM')) process.exit(143);
|
|
19
|
+
};
|
|
20
|
+
process.once('disconnect', stop);
|
|
21
|
+
if (!process.connected) stop();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function runCoreBootstrap() {
|
|
25
|
+
bindInteractiveTerminalOwner();
|
|
26
|
+
const args = process.argv.slice(2);
|
|
27
|
+
const informational = isStandaloneHelpRequest(args) || isReadOnlyInspectionRequest(args);
|
|
28
|
+
let diagnostics;
|
|
29
|
+
if (!informational) {
|
|
30
|
+
try { diagnostics = installWindowsNodeCrashDump({ homeDir: process.env.BLUN_HOME }); } catch {}
|
|
31
|
+
}
|
|
32
|
+
const packageRoot = path.resolve(__dirname, '..');
|
|
33
|
+
const mainPath = path.join(packageRoot, 'blun.mjs');
|
|
34
|
+
let leaseResult;
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
leaseResult = await acquireSharedRuntimeLease({ packageRoot });
|
|
38
|
+
if (!leaseResult.acquired) throw new Error('RUNTIME_PROTECTION_UNAVAILABLE');
|
|
39
|
+
leaseResult.lease.assertOwned();
|
|
40
|
+
process.argv = [process.execPath, mainPath, ...process.argv.slice(2)];
|
|
41
|
+
await import(pathToFileURL(mainPath).href);
|
|
42
|
+
leaseResult.lease.assertOwned();
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (!informational) {
|
|
45
|
+
try {
|
|
46
|
+
if (diagnostics?.enabled) diagnostics.write(error, 'bootstrap-failure');
|
|
47
|
+
else recordRuntimeExit({ homeDir: process.env.BLUN_HOME, source: 'bootstrap',
|
|
48
|
+
kind: 'bootstrap-failure', phase: 'startup', error });
|
|
49
|
+
} catch {}
|
|
50
|
+
}
|
|
51
|
+
try { diagnostics?.dispose(); } catch {}
|
|
52
|
+
try { await leaseResult?.lease?.release(); }
|
|
53
|
+
catch (leaseError) {
|
|
54
|
+
if (!informational) {
|
|
55
|
+
try {
|
|
56
|
+
recordRuntimeExit({ homeDir: process.env.BLUN_HOME, source: 'bootstrap',
|
|
57
|
+
kind: 'lease-release-failure', phase: 'cleanup', error: leaseError });
|
|
58
|
+
} catch {}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// The bundled CLI loads package assets lazily after module evaluation. Keep
|
|
65
|
+
// the install lease for this process's lifetime, without keeping print/help
|
|
66
|
+
// commands alive solely because of the owner server.
|
|
67
|
+
leaseResult.lease.unref();
|
|
68
|
+
|
|
69
|
+
if (process.connected) {
|
|
70
|
+
try {
|
|
71
|
+
process.send({ type: CORE_LOADED_MESSAGE }, () => {
|
|
72
|
+
if (process.env.BLUN_TERMINAL_OWNER === '1') {
|
|
73
|
+
process.channel?.unref();
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
process.disconnect();
|
|
78
|
+
} catch {}
|
|
79
|
+
});
|
|
80
|
+
} catch {}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (require.main === module) {
|
|
85
|
+
// oxlint-disable-next-line unicorn/prefer-top-level-await -- Worker entry is CommonJS.
|
|
86
|
+
void runCoreBootstrap().catch((error) => {
|
|
87
|
+
const message = error && error.message ? error.message : String(error);
|
|
88
|
+
fs.writeSync(process.stderr.fd, `BLUN Start fehlgeschlagen: ${message}\n`);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
module.exports = { CORE_LOADED_MESSAGE, runCoreBootstrap };
|
package/bin/launcher-mode.js
CHANGED
|
@@ -1,93 +1,126 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const fs = require('node:fs');
|
|
4
|
-
const path = require('node:path');
|
|
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
|
-
if (
|
|
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
|
-
function
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { parseArgs } = require('node:util');
|
|
6
|
+
|
|
7
|
+
const LAUNCHER_MODES = Object.freeze({
|
|
8
|
+
BLUN: 'blun',
|
|
9
|
+
KING: 'king',
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const SETUP_INSPECTION_OPTIONS = new Set([
|
|
13
|
+
'--json', '--reference', '--proposal', '--validate', '--document', '--query', '--target',
|
|
14
|
+
]);
|
|
15
|
+
const CONFIG_INSPECTION_COMMANDS = new Set(['validate', 'inspect', 'preview']);
|
|
16
|
+
|
|
17
|
+
const LAUNCHER_HELP_TEXT = [
|
|
18
|
+
'',
|
|
19
|
+
'Launchers:',
|
|
20
|
+
' blun Starts the CLI without automatically attaching Telegram.',
|
|
21
|
+
' king Starts the same CLI and automatically attaches the configured Telegram channel.',
|
|
22
|
+
' Both use the same version, account, model, and commands.',
|
|
23
|
+
' blun tools list shows optional tools; enable writes only explicit choices.',
|
|
24
|
+
'',
|
|
25
|
+
].join('\n');
|
|
26
|
+
|
|
27
|
+
function launcherModeFromArgv(argv) {
|
|
28
|
+
const entry = argv[1] || '';
|
|
29
|
+
const filename = entry.replaceAll('\\', '/').split('/').pop() || '';
|
|
30
|
+
const command = filename.replace(/\.(?:c|m)?js$/i, '').toLowerCase();
|
|
31
|
+
return command === LAUNCHER_MODES.KING ? LAUNCHER_MODES.KING : LAUNCHER_MODES.BLUN;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function runtimePolicyEnvironment(blunDir) {
|
|
35
|
+
if (blunDir === undefined) return {};
|
|
36
|
+
let policy;
|
|
37
|
+
try {
|
|
38
|
+
if (!path.isAbsolute(blunDir)) throw new Error('Invalid home');
|
|
39
|
+
const file = path.join(blunDir, 'runtime-policy.json');
|
|
40
|
+
const stat = fs.lstatSync(file);
|
|
41
|
+
if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 4096) throw new Error('Invalid file');
|
|
42
|
+
policy = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (error.code === 'ENOENT') return {};
|
|
45
|
+
throw new Error('Invalid BLUN runtime policy');
|
|
46
|
+
}
|
|
47
|
+
const review = policy?.responseReview;
|
|
48
|
+
if (policy?.schema !== 'blun.runtime-policy/v1'
|
|
49
|
+
|| Object.keys(policy).sort().join(',') !== 'responseReview,schema'
|
|
50
|
+
|| !review || Object.keys(review).sort().join(',') !== 'guardVersion,language,required'
|
|
51
|
+
|| review.required !== true || typeof review.language !== 'string'
|
|
52
|
+
|| !/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/.test(review.language)
|
|
53
|
+
|| /^(auto|all)$/i.test(review.language)
|
|
54
|
+
|| typeof review.guardVersion !== 'string' || !/^\d+\.\d+\.\d+$/.test(review.guardVersion)) {
|
|
55
|
+
throw new Error('Invalid BLUN runtime policy');
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
BLUN_LANGUAGE_GUARD_MANDATORY: '1',
|
|
59
|
+
BLUN_LANGUAGE_GUARD_LANGUAGE: review.language,
|
|
60
|
+
BLUN_LANGUAGE_GUARD_VERSION: review.guardVersion,
|
|
61
|
+
BLUN_TELEGRAM_LANGUAGE_GATE: 'required',
|
|
62
|
+
BLUN_TELEGRAM_OUTPUT_LOCALE: review.language,
|
|
63
|
+
AGENTSPINE_STATE_DIR: path.join(blunDir, 'state', 'agent-spine'),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function createLauncherEnvironment(sourceEnv, mode, publicPackageVersion, blunDir) {
|
|
68
|
+
return {
|
|
69
|
+
...sourceEnv,
|
|
70
|
+
...runtimePolicyEnvironment(blunDir),
|
|
71
|
+
BLUN_NO_AUTO_UPDATE: '1',
|
|
72
|
+
BLUN_PUBLIC_PACKAGE_VERSION: publicPackageVersion,
|
|
73
|
+
BLUN_TELEGRAM_ATTACH: mode === LAUNCHER_MODES.KING ? 'on' : 'off',
|
|
74
|
+
BLUN_TELEGRAM_HEADLESS: 'off',
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function isNpmPackageUpdateRequest(args) {
|
|
79
|
+
if (!Array.isArray(args) || args.length !== 1) return false;
|
|
80
|
+
const command = String(args[0] || '').toLowerCase();
|
|
81
|
+
return command === 'update' || command === 'upgrade';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function isStandaloneHelpRequest(args) {
|
|
85
|
+
return Array.isArray(args) && args.length === 1 && (args[0] === '--help' || args[0] === '-h');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function isReadOnlySetupRequest(args) {
|
|
89
|
+
return Array.isArray(args) && args[0] === 'setup'
|
|
90
|
+
&& args.slice(1).some(value => typeof value === 'string' && SETUP_INSPECTION_OPTIONS.has(value.split('=', 1)[0]));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function isReadOnlyInspectionRequest(args) {
|
|
94
|
+
return isReadOnlySetupRequest(args)
|
|
95
|
+
|| (Array.isArray(args) && args[0] === 'config' && CONFIG_INSPECTION_COMMANDS.has(args[1]))
|
|
96
|
+
|| (Array.isArray(args) && args[0] === 'docs')
|
|
97
|
+
|| isReadOnlyDoctorRequest(args);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function isReadOnlyDoctorRequest(args) {
|
|
101
|
+
if (!Array.isArray(args) || args[0] !== 'doctor') return false;
|
|
102
|
+
try {
|
|
103
|
+
const { positionals } = parseArgs({ args: args.slice(1), allowPositionals: true,
|
|
104
|
+
options: { json: { type: 'boolean' }, schema: { type: 'boolean' }, help: { type: 'boolean', short: 'h' } } });
|
|
105
|
+
if (positionals.length === 0) return true;
|
|
106
|
+
if (positionals[0] === 'config' || positionals[0] === 'tui') return positionals.length <= 2;
|
|
107
|
+
return positionals[0] === 'mcp' && positionals.length === 2;
|
|
108
|
+
} catch {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function launcherHelpText() {
|
|
114
|
+
return LAUNCHER_HELP_TEXT;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module.exports = {
|
|
118
|
+
LAUNCHER_MODES,
|
|
119
|
+
createLauncherEnvironment,
|
|
120
|
+
isNpmPackageUpdateRequest,
|
|
121
|
+
isStandaloneHelpRequest,
|
|
122
|
+
isReadOnlySetupRequest,
|
|
123
|
+
isReadOnlyInspectionRequest,
|
|
124
|
+
launcherHelpText,
|
|
125
|
+
launcherModeFromArgv,
|
|
126
|
+
};
|
package/bin/launcher-runtime.js
CHANGED
|
@@ -13,6 +13,7 @@ const {
|
|
|
13
13
|
createLauncherEnvironment,
|
|
14
14
|
isNpmPackageUpdateRequest,
|
|
15
15
|
isStandaloneHelpRequest,
|
|
16
|
+
isReadOnlyInspectionRequest,
|
|
16
17
|
launcherHelpText,
|
|
17
18
|
launcherModeFromArgv,
|
|
18
19
|
} = require('./launcher-mode');
|
|
@@ -39,6 +40,7 @@ const {
|
|
|
39
40
|
writePrivateFile,
|
|
40
41
|
} = require('./private-paths');
|
|
41
42
|
|
|
43
|
+
const { writeTelegramTemplate } = require('./rename-private-staging.cjs');
|
|
42
44
|
const PKG = path.resolve(__dirname, '..');
|
|
43
45
|
const ARGS = process.argv.slice(2);
|
|
44
46
|
|
|
@@ -50,6 +52,34 @@ function resolveLauncherPrivatePaths(options = {}) {
|
|
|
50
52
|
const env = options.env || process.env;
|
|
51
53
|
const platform = options.platform || process.platform;
|
|
52
54
|
const configuredHome = String(env.BLUN_HOME || '').trim();
|
|
55
|
+
const stateDir = String(env.BLUN_STATE_DIR || '').trim();
|
|
56
|
+
if (stateDir) {
|
|
57
|
+
const paths = platform === 'win32' ? path.win32 : path.posix;
|
|
58
|
+
if (!paths.isAbsolute(stateDir) || (platform === 'win32' && !/^[A-Za-z]:[\\/]/u.test(stateDir))) {
|
|
59
|
+
throw new Error('BLUN_STATE_DIR must be an absolute local path.');
|
|
60
|
+
}
|
|
61
|
+
const blunHome = paths.resolve(stateDir);
|
|
62
|
+
const fsImpl = options.fsImpl || fs;
|
|
63
|
+
let ancestor = blunHome;
|
|
64
|
+
for (;;) {
|
|
65
|
+
try {
|
|
66
|
+
const stat = fsImpl.lstatSync(ancestor);
|
|
67
|
+
const realpath = fsImpl.realpathSync.native || fsImpl.realpathSync;
|
|
68
|
+
const canonical = realpath(ancestor);
|
|
69
|
+
const normalize = platform === 'win32' ? normalizeWindowsPath : paths.normalize;
|
|
70
|
+
if (!stat.isDirectory() || stat.isSymbolicLink() || normalize(canonical) !== normalize(ancestor)) {
|
|
71
|
+
throw new Error('BLUN_STATE_DIR must not traverse a symbolic link or junction.');
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (error.code !== 'ENOENT') throw error;
|
|
76
|
+
const parent = paths.dirname(ancestor);
|
|
77
|
+
if (parent === ancestor) throw error;
|
|
78
|
+
ancestor = parent;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return { blunHome, userHome: (options.homedir || os.homedir)() };
|
|
82
|
+
}
|
|
53
83
|
if (platform !== 'win32') {
|
|
54
84
|
const userHome = (options.homedir || os.homedir)();
|
|
55
85
|
return {
|
|
@@ -224,7 +254,7 @@ function installTelegramForProfile(packageRoot, blunDir) {
|
|
|
224
254
|
ensurePrivateDirectory(channelDir);
|
|
225
255
|
const envFile = path.join(channelDir, '.env');
|
|
226
256
|
if (!fs.existsSync(envFile)) {
|
|
227
|
-
|
|
257
|
+
writeTelegramTemplate(envFile, 'BLUN_TELEGRAM_BOT_TOKEN=HIER_DEIN_BOT_TOKEN_EINFUEGEN\n');
|
|
228
258
|
} else {
|
|
229
259
|
securePrivateFile(envFile);
|
|
230
260
|
}
|
|
@@ -369,6 +399,22 @@ async function runLauncher(options = {}) {
|
|
|
369
399
|
return;
|
|
370
400
|
}
|
|
371
401
|
|
|
402
|
+
if (isReadOnlyInspectionRequest(ARGS)) {
|
|
403
|
+
const compatibilityError = unsupportedNodeMessage(process.versions.node, process.platform);
|
|
404
|
+
if (compatibilityError !== null) {
|
|
405
|
+
process.stderr.write(`${compatibilityError}\n`);
|
|
406
|
+
process.exitCode = 1;
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
const blunDir = resolveLauncherPrivatePaths().blunHome;
|
|
410
|
+
require('./verify-bundled-agent-sources.cjs').verifyBundledAgentSources(PKG);
|
|
411
|
+
const env = createLauncherEnvironment(process.env, LAUNCHER_MODES.BLUN, readPackageVersion(), blunDir);
|
|
412
|
+
env.BLUN_HOME = blunDir;
|
|
413
|
+
if (String(process.env.BLUN_STATE_DIR || '').trim()) env.BLUN_SHARED_HOME = blunDir;
|
|
414
|
+
process.exitCode = await runInformationalCore(ARGS, env, callerCwd, releaseNotice);
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
|
|
372
418
|
let privatePaths;
|
|
373
419
|
const getPrivatePaths = () => {
|
|
374
420
|
privatePaths ||= resolveLauncherPrivatePaths();
|
|
@@ -453,13 +499,31 @@ async function runLauncher(options = {}) {
|
|
|
453
499
|
installTelegramForProfile(PKG, blunDir);
|
|
454
500
|
}
|
|
455
501
|
|
|
456
|
-
const
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
502
|
+
const nativeOwner = new AbortController();
|
|
503
|
+
let nativeStopSignal;
|
|
504
|
+
const nativeSignals = new Map();
|
|
505
|
+
for (const signal of ['SIGHUP', 'SIGINT', 'SIGTERM']) {
|
|
506
|
+
const handler = () => { nativeStopSignal = signal; nativeOwner.abort(); };
|
|
507
|
+
nativeSignals.set(signal, handler);
|
|
508
|
+
process.once(signal, handler);
|
|
509
|
+
}
|
|
510
|
+
let nativeModules;
|
|
511
|
+
try {
|
|
512
|
+
nativeModules = await repairConfiguredNativeModules({
|
|
513
|
+
blunDir,
|
|
514
|
+
callerCwd,
|
|
515
|
+
signal: nativeOwner.signal,
|
|
516
|
+
onRepairStart() {
|
|
517
|
+
process.stdout.write('BLUN richtet native Node.js-Module fuer die neue Laufzeit ein.\n');
|
|
518
|
+
},
|
|
519
|
+
});
|
|
520
|
+
} catch (error) {
|
|
521
|
+
if (!nativeOwner.signal.aborted) throw error;
|
|
522
|
+
process.exitCode = nativeStopSignal === 'SIGINT' ? 130 : nativeStopSignal === 'SIGHUP' ? 129 : 143;
|
|
523
|
+
return;
|
|
524
|
+
} finally {
|
|
525
|
+
for (const [signal, handler] of nativeSignals) process.removeListener(signal, handler);
|
|
526
|
+
}
|
|
463
527
|
if (nativeModules.repaired.length > 0) {
|
|
464
528
|
process.stdout.write('Native Node.js-Module sind wieder einsatzbereit.\n');
|
|
465
529
|
}
|
|
@@ -467,6 +531,7 @@ async function runLauncher(options = {}) {
|
|
|
467
531
|
// --- 6. Start -----------------------------------------------------------
|
|
468
532
|
const env = createLauncherEnvironment(process.env, mode, readPackageVersion(), blunDir);
|
|
469
533
|
env.BLUN_HOME = blunDir;
|
|
534
|
+
if (String(process.env.BLUN_STATE_DIR || '').trim()) env.BLUN_SHARED_HOME = blunDir;
|
|
470
535
|
process.exitCode = await superviseProtectedCore(
|
|
471
536
|
ARGS,
|
|
472
537
|
env,
|