@helix3/helix-cli 0.1.18-helix3.267 → 0.1.18-helix3.269
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/bridge-plugins/helix.bridge.unreal/bin/unreal-skeletal-mesh-extract.js +108 -6
- package/bridge-plugins/helix.bridge.unreal/test/handler.test.js +69 -1
- package/dist/bridge/execute.js +11 -2
- package/dist/bridge/execute.js.map +1 -1
- package/dist/bridge/types.d.ts +9 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_abs.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_expression.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_jbeam.cpython-312.pyc +0 -0
- package/plugins/beamng-vehicle/bin/__pycache__/beamng_materials.cpython-312.pyc +0 -0
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
const { spawn, spawnSync } = require('node:child_process');
|
|
5
5
|
const { createHash } = require('node:crypto');
|
|
6
6
|
const {
|
|
7
|
+
chmodSync,
|
|
7
8
|
closeSync,
|
|
8
9
|
existsSync,
|
|
9
10
|
lstatSync,
|
|
@@ -13,8 +14,9 @@ const {
|
|
|
13
14
|
readdirSync,
|
|
14
15
|
realpathSync,
|
|
15
16
|
statSync,
|
|
17
|
+
writeFileSync,
|
|
16
18
|
} = require('node:fs');
|
|
17
|
-
const { basename, extname, isAbsolute, join, relative, resolve, sep } = require('node:path');
|
|
19
|
+
const { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } = require('node:path');
|
|
18
20
|
|
|
19
21
|
const REQUEST_SCHEMA = 'helix.bridge-plugin-request/1';
|
|
20
22
|
const PROFILE_SCHEMA = 'helix.bridge.unreal-asset/1';
|
|
@@ -251,6 +253,60 @@ function findProject(sourcePath) {
|
|
|
251
253
|
return projects[0];
|
|
252
254
|
}
|
|
253
255
|
|
|
256
|
+
/**
|
|
257
|
+
* A "Game Features" category plugin marked `"ExplicitlyLoaded": true` in its
|
|
258
|
+
* .uplugin (HELIX's character-content plugins all are) is deliberately
|
|
259
|
+
* excluded from Unreal's built-in game-feature startup scan
|
|
260
|
+
* (`UGameFeaturesSubsystem::LoadBuiltInGameFeaturePlugins` filters
|
|
261
|
+
* `IPluginManager::GetEnabledPlugins()` down to `GetPluginsEnabledAtStartup()`,
|
|
262
|
+
* which explicit-load plugins are not part of). Its C++ modules still load
|
|
263
|
+
* from being listed in the .uproject's `Plugins` array, but its Content
|
|
264
|
+
* folder is never mounted as a package path root — so any package path under
|
|
265
|
+
* it (e.g. `/HelixCharacterCreator/...`) fails to resolve with Unreal's own
|
|
266
|
+
* "does not map to a root" error. Normal interactive/gameplay sessions
|
|
267
|
+
* activate it through a runtime Game Feature request that a bare
|
|
268
|
+
* `-ExecutePythonScript` extraction session never makes, and no amount of
|
|
269
|
+
* waiting resolves it (measured: 6 minutes of polling every 10s never
|
|
270
|
+
* mounted it).
|
|
271
|
+
*
|
|
272
|
+
* The extract capability only reads content — it has no use for Game
|
|
273
|
+
* Feature runtime state — so on this capability's own already-immutable
|
|
274
|
+
* project snapshot (never the caller's real source), flip
|
|
275
|
+
* `ExplicitlyLoaded` to `false` for every such plugin before invoking the
|
|
276
|
+
* editor. That makes Unreal mount its Content like any ordinary enabled
|
|
277
|
+
* plugin, deterministically, with no dependency on Game Feature activation
|
|
278
|
+
* or timing.
|
|
279
|
+
*/
|
|
280
|
+
function mountExplicitlyLoadedGameFeaturePlugins(uprojectPath) {
|
|
281
|
+
const pluginsDir = join(dirname(uprojectPath), 'Plugins');
|
|
282
|
+
if (!existsSync(pluginsDir)) return;
|
|
283
|
+
for (const entry of readdirSync(pluginsDir, { withFileTypes: true })) {
|
|
284
|
+
if (!entry.isDirectory() || entry.isSymbolicLink()) continue;
|
|
285
|
+
const pluginDir = join(pluginsDir, entry.name);
|
|
286
|
+
for (const file of readdirSync(pluginDir, { withFileTypes: true })) {
|
|
287
|
+
if (!file.isFile() || file.isSymbolicLink() || extname(file.name).toLowerCase() !== '.uplugin') continue;
|
|
288
|
+
const upluginPath = join(pluginDir, file.name);
|
|
289
|
+
let descriptor;
|
|
290
|
+
try {
|
|
291
|
+
descriptor = JSON.parse(readFileSync(upluginPath, 'utf8'));
|
|
292
|
+
} catch {
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
if (descriptor.ExplicitlyLoaded !== true) continue;
|
|
296
|
+
descriptor.ExplicitlyLoaded = false;
|
|
297
|
+
try {
|
|
298
|
+
chmodSync(upluginPath, 0o644);
|
|
299
|
+
writeFileSync(upluginPath, `${JSON.stringify(descriptor, null, '\t')}\n`);
|
|
300
|
+
} catch (error) {
|
|
301
|
+
process.stderr.write(
|
|
302
|
+
`HELIX Unreal Bridge warning: could not mount explicitly-loaded plugin '${entry.name}' ` +
|
|
303
|
+
`for extraction (left as-is; its content will not resolve): ${error.message}\n`,
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
254
310
|
function runningInWsl() {
|
|
255
311
|
if (process.platform !== 'linux') return false;
|
|
256
312
|
if (process.env.WSL_DISTRO_NAME || process.env.WSL_INTEROP) return true;
|
|
@@ -274,14 +330,15 @@ function wslPath(mode, path) {
|
|
|
274
330
|
return result.stdout.trim();
|
|
275
331
|
}
|
|
276
332
|
|
|
277
|
-
function editorInvocationPaths(editor, project, script, outputs) {
|
|
333
|
+
function editorInvocationPaths(editor, project, script, outputs, log) {
|
|
278
334
|
const wsl = runningInWsl();
|
|
279
|
-
if (!wsl) return { editor, project, script, outputs, wsl };
|
|
335
|
+
if (!wsl) return { editor, project, script, outputs, log, wsl };
|
|
280
336
|
return {
|
|
281
337
|
editor: WINDOWS_ABSOLUTE_PATH.test(editor) ? wslPath('-u', editor) : editor,
|
|
282
338
|
project: wslPath('-w', project),
|
|
283
339
|
script: wslPath('-w', script),
|
|
284
340
|
outputs: outputs.map((output) => wslPath('-w', output)),
|
|
341
|
+
log: wslPath('-w', log),
|
|
285
342
|
wsl,
|
|
286
343
|
};
|
|
287
344
|
}
|
|
@@ -359,6 +416,39 @@ async function runEditor(editor, args, environment, wsl) {
|
|
|
359
416
|
});
|
|
360
417
|
}
|
|
361
418
|
|
|
419
|
+
const ENGINE_LOG_TAIL_BYTES = 64 * 1024;
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Read the trailing bytes of the real Unreal Editor engine log (written via
|
|
423
|
+
* `-abslog`), not the captured stdout/stderr tail, which is capped at
|
|
424
|
+
* LOG_TAIL_BYTES and can lose the actual Python traceback under the noise UE
|
|
425
|
+
* prints on the way to a clean `-unattended` shutdown. Returns null when the
|
|
426
|
+
* log was never written (e.g. the editor failed to start at all).
|
|
427
|
+
*/
|
|
428
|
+
function readEngineLogTail(path, maxBytes) {
|
|
429
|
+
let info;
|
|
430
|
+
try {
|
|
431
|
+
info = statSync(path);
|
|
432
|
+
} catch {
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
if (!info.isFile()) return null;
|
|
436
|
+
const length = Math.min(maxBytes, info.size);
|
|
437
|
+
const start = info.size - length;
|
|
438
|
+
const buffer = Buffer.alloc(length);
|
|
439
|
+
let descriptor;
|
|
440
|
+
try {
|
|
441
|
+
descriptor = openSync(path, 'r');
|
|
442
|
+
readSync(descriptor, buffer, 0, length, start);
|
|
443
|
+
} catch (error) {
|
|
444
|
+
return `(could not read '${path}': ${error.message})`;
|
|
445
|
+
} finally {
|
|
446
|
+
if (descriptor !== undefined) closeSync(descriptor);
|
|
447
|
+
}
|
|
448
|
+
const text = buffer.toString('utf8').trim();
|
|
449
|
+
return start > 0 ? `…(truncated, showing last ${length} of ${info.size} bytes)…\n${text}` : text;
|
|
450
|
+
}
|
|
451
|
+
|
|
362
452
|
function editorFailure(outcome) {
|
|
363
453
|
return `Unreal Editor failed${outcome.signal ? ` with signal ${outcome.signal}` : ` with exit ${outcome.code}`}` +
|
|
364
454
|
`${outcome.tail ? `: ${outcome.tail}` : ''}`;
|
|
@@ -433,7 +523,8 @@ function validateTextureBinding(value, outputRoot, label) {
|
|
|
433
523
|
}
|
|
434
524
|
const colorSpace = object(binding.colorSpace, `${label}.colorSpace`);
|
|
435
525
|
const colorKeys = Object.keys(colorSpace).sort();
|
|
436
|
-
|
|
526
|
+
const SUPPORTED_COLOR_SPACE_KEYS = ['compressionSettings', 'flipGreenChannel', 'srgb'];
|
|
527
|
+
if (colorKeys.some((key) => !SUPPORTED_COLOR_SPACE_KEYS.includes(key))) {
|
|
437
528
|
fail(`${label}.colorSpace contains unsupported metadata`);
|
|
438
529
|
}
|
|
439
530
|
if ('srgb' in colorSpace && typeof colorSpace.srgb !== 'boolean') {
|
|
@@ -442,6 +533,9 @@ function validateTextureBinding(value, outputRoot, label) {
|
|
|
442
533
|
if ('compressionSettings' in colorSpace) {
|
|
443
534
|
nonEmptyString(colorSpace.compressionSettings, `${label}.colorSpace.compressionSettings`);
|
|
444
535
|
}
|
|
536
|
+
if ('flipGreenChannel' in colorSpace && typeof colorSpace.flipGreenChannel !== 'boolean') {
|
|
537
|
+
fail(`${label}.colorSpace.flipGreenChannel must be a boolean`);
|
|
538
|
+
}
|
|
445
539
|
|
|
446
540
|
const texturePath = resolve(outputRoot, relativePath);
|
|
447
541
|
containedPath(outputRoot, texturePath, label);
|
|
@@ -571,6 +665,7 @@ async function main() {
|
|
|
571
665
|
const { sourcePath, outputDir, profilePath } = validateRequest(request);
|
|
572
666
|
const profiles = validateProfile(readJsonFile(profilePath, 'Unreal asset profile'));
|
|
573
667
|
const project = findProject(sourcePath);
|
|
668
|
+
mountExplicitlyLoadedGameFeaturePlugins(project);
|
|
574
669
|
const outputs = profiles.map((profile) => join(outputDir, `${profile.slug}.fbx`));
|
|
575
670
|
const script = resolve(__dirname, '..', 'unreal', 'export_skeletal_mesh.py');
|
|
576
671
|
if (!existsSync(script)) fail(`Packaged Unreal Python exporter is missing: ${script}`);
|
|
@@ -582,7 +677,8 @@ async function main() {
|
|
|
582
677
|
}
|
|
583
678
|
|
|
584
679
|
const editorValue = nonEmptyString(process.env.HELIX_UNREAL_EDITOR, 'HELIX_UNREAL_EDITOR');
|
|
585
|
-
const
|
|
680
|
+
const engineLogPath = join(outputDir, 'unreal-editor-full.log');
|
|
681
|
+
const paths = editorInvocationPaths(editorValue, project, script, outputs, engineLogPath);
|
|
586
682
|
const environment = {
|
|
587
683
|
...process.env,
|
|
588
684
|
HELIX_UNREAL_ASSET_PATH: profiles[0].assetPath,
|
|
@@ -605,12 +701,18 @@ async function main() {
|
|
|
605
701
|
'-nop4',
|
|
606
702
|
'-nosplash',
|
|
607
703
|
'-nosound',
|
|
704
|
+
'-log',
|
|
705
|
+
`-abslog=${paths.log}`,
|
|
608
706
|
], editorEnvironment(environment, paths.wsl), paths.wsl);
|
|
609
707
|
|
|
610
708
|
const invalidOutputs = outputs.map(validateFbxOutput).filter(Boolean);
|
|
611
709
|
if (invalidOutputs.length > 0) {
|
|
612
710
|
const suffix = editorOutcome.code === 0 && !editorOutcome.signal ? '' : `; ${editorFailure(editorOutcome)}`;
|
|
613
|
-
|
|
711
|
+
const engineLogTail = readEngineLogTail(engineLogPath, ENGINE_LOG_TAIL_BYTES);
|
|
712
|
+
const logSuffix = engineLogTail
|
|
713
|
+
? `\nUnreal Editor engine log (${engineLogPath}):\n${engineLogTail}`
|
|
714
|
+
: `\n(Unreal Editor engine log not found at ${engineLogPath})`;
|
|
715
|
+
fail(`Unreal Editor did not produce the complete reviewed export set (${invalidOutputs.join(', ')})${suffix}${logSuffix}`);
|
|
614
716
|
}
|
|
615
717
|
const materialSidecars = profiles.map((profile) => validateMaterialSidecar(
|
|
616
718
|
join(outputDir, `${profile.slug}.materials.json`),
|
|
@@ -61,13 +61,19 @@ function fixture(profileOverrides = {}) {
|
|
|
61
61
|
" if (process.env.HELIX_TEST_SIDECAR_KIND === 'missing') continue;",
|
|
62
62
|
" const bindingSha = process.env.HELIX_TEST_SIDECAR_KIND === 'hash-mismatch' ? 'f'.repeat(64) : textureSha;",
|
|
63
63
|
" const bindingPath = process.env.HELIX_TEST_SIDECAR_KIND === 'escape' ? '../escaped.png' : 'textures/' + bindingSha + '.png';",
|
|
64
|
-
" const
|
|
64
|
+
" const colorSpace = { srgb: true, compressionSettings: 'TC_Default' };",
|
|
65
|
+
" if (process.env.HELIX_TEST_SIDECAR_KIND === 'flip-green') colorSpace.flipGreenChannel = true;",
|
|
66
|
+
" const sidecar = { schemaVersion: 'helix.bridge.unreal-material-sidecar/1', asset: { slug: job.slug, sourceMeshAssetPath: job.assetPath }, materials: [{ slotIndex: 0, slotName: 'Body', importedSlotName: 'Body_skin00', sourceMaterialAssetPath: '/Game/Materials/MI_Body.MI_Body', sourceRootMaterialAssetPath: '/Game/Materials/M_Body.M_Body', parameters: { scalars: { Roughness: 0.5 }, vectors: { Tint: { r: 1, g: 0.5, b: 0.25, a: 1 } }, textures: { BaseColor: { sourceAssetPath: '/Game/Textures/T_Body.T_Body', path: bindingPath, sha256: bindingSha, sizeBytes: textureBytes.length, colorSpace } } } }] };",
|
|
65
67
|
" const sidecarPath = join(dirname(job.outputPath), job.slug + '.materials.json');",
|
|
66
68
|
" if (process.env.HELIX_TEST_SIDECAR_KIND === 'corrupt') writeFileSync(sidecarPath, '{');",
|
|
67
69
|
" else if (process.env.HELIX_TEST_SIDECAR_KIND === 'symlink') symlinkSync(process.env.HELIX_TEST_INVOCATION, sidecarPath);",
|
|
68
70
|
" else writeFileSync(sidecarPath, JSON.stringify(sidecar));",
|
|
69
71
|
"}",
|
|
70
72
|
"if (process.env.HELIX_TEST_EDITOR_LOG) process.stderr.write(process.env.HELIX_TEST_EDITOR_LOG);",
|
|
73
|
+
"if (process.env.HELIX_TEST_ABSLOG_CONTENT) {",
|
|
74
|
+
" const abslogArg = process.argv.slice(2).find((arg) => arg.startsWith('-abslog='));",
|
|
75
|
+
" if (abslogArg) writeFileSync(abslogArg.slice('-abslog='.length), process.env.HELIX_TEST_ABSLOG_CONTENT);",
|
|
76
|
+
"}",
|
|
71
77
|
"if (process.env.HELIX_TEST_EDITOR_SIGNAL) process.kill(process.pid, process.env.HELIX_TEST_EDITOR_SIGNAL);",
|
|
72
78
|
"if (process.env.HELIX_TEST_EDITOR_EXIT) process.exit(Number(process.env.HELIX_TEST_EDITOR_EXIT));",
|
|
73
79
|
].join('\n'));
|
|
@@ -119,12 +125,50 @@ test('exports one configured skeletal mesh with the full Unreal editor script',
|
|
|
119
125
|
assert.match(invocation.args[1], /^-ExecutePythonScript=.*export_skeletal_mesh\.py$/);
|
|
120
126
|
assert.ok(invocation.args.includes('-stdout'));
|
|
121
127
|
assert.ok(invocation.args.includes('-FullStdOutLogOutput'));
|
|
128
|
+
assert.ok(invocation.args.includes('-log'));
|
|
129
|
+
assert.ok(invocation.args.some((arg) => arg.startsWith('-abslog=')));
|
|
122
130
|
assert.match(readFileSync(join(entry.output, 'base-male.fbx'), 'binary'), /^Kaydara FBX Binary/);
|
|
123
131
|
const sidecar = JSON.parse(readFileSync(join(entry.output, 'base-male.materials.json'), 'utf8'));
|
|
124
132
|
assert.equal(sidecar.materials[0].parameters.scalars.Roughness, 0.5);
|
|
125
133
|
assert.deepEqual(sidecar.materials[0].parameters.vectors.Tint, { r: 1, g: 0.5, b: 0.25, a: 1 });
|
|
126
134
|
});
|
|
127
135
|
|
|
136
|
+
test('mounts an ExplicitlyLoaded Game Features plugin before extraction, and leaves other plugins alone', () => {
|
|
137
|
+
const entry = fixture();
|
|
138
|
+
const explicitPluginDir = join(entry.project, 'Plugins', 'HelixCharacterCreator');
|
|
139
|
+
mkdirSync(join(explicitPluginDir, 'Content'), { recursive: true });
|
|
140
|
+
const explicitPluginPath = join(explicitPluginDir, 'HelixCharacterCreator.uplugin');
|
|
141
|
+
writeFileSync(explicitPluginPath, JSON.stringify({
|
|
142
|
+
FileVersion: 3,
|
|
143
|
+
FriendlyName: 'HelixCharacterCreator',
|
|
144
|
+
Category: 'Game Features',
|
|
145
|
+
CanContainContent: true,
|
|
146
|
+
ExplicitlyLoaded: true,
|
|
147
|
+
BuiltInInitialFeatureState: 'Registered',
|
|
148
|
+
}));
|
|
149
|
+
chmodSync(explicitPluginPath, 0o444); // Perforce-style read-only, like the real content.
|
|
150
|
+
|
|
151
|
+
const implicitPluginDir = join(entry.project, 'Plugins', 'SomeOrdinaryPlugin');
|
|
152
|
+
mkdirSync(join(implicitPluginDir, 'Content'), { recursive: true });
|
|
153
|
+
const implicitPluginPath = join(implicitPluginDir, 'SomeOrdinaryPlugin.uplugin');
|
|
154
|
+
writeFileSync(implicitPluginPath, JSON.stringify({
|
|
155
|
+
FileVersion: 3,
|
|
156
|
+
FriendlyName: 'SomeOrdinaryPlugin',
|
|
157
|
+
CanContainContent: true,
|
|
158
|
+
ExplicitlyLoaded: false,
|
|
159
|
+
}));
|
|
160
|
+
|
|
161
|
+
const result = run(entry);
|
|
162
|
+
assert.equal(result.status, 0, result.stderr);
|
|
163
|
+
|
|
164
|
+
const patched = JSON.parse(readFileSync(explicitPluginPath, 'utf8'));
|
|
165
|
+
assert.equal(patched.ExplicitlyLoaded, false);
|
|
166
|
+
assert.equal(patched.Category, 'Game Features', 'only the loading gate changes, not the plugin identity');
|
|
167
|
+
|
|
168
|
+
const untouched = JSON.parse(readFileSync(implicitPluginPath, 'utf8'));
|
|
169
|
+
assert.equal(untouched.ExplicitlyLoaded, false);
|
|
170
|
+
});
|
|
171
|
+
|
|
128
172
|
test('accepts a structurally valid ASCII FBX export', () => {
|
|
129
173
|
const entry = fixture();
|
|
130
174
|
const result = run(entry, { HELIX_TEST_OUTPUT_KIND: 'ascii' });
|
|
@@ -171,6 +215,18 @@ test('rejects a corrupt file even when Unreal exits successfully', () => {
|
|
|
171
215
|
assert.match(result.stderr, /not a structurally valid FBX/);
|
|
172
216
|
});
|
|
173
217
|
|
|
218
|
+
test('surfaces the real engine log tail, not just the truncated stdout tail, when the export set is incomplete', () => {
|
|
219
|
+
const entry = fixture();
|
|
220
|
+
const result = run(entry, {
|
|
221
|
+
HELIX_TEST_OUTPUT_KIND: 'missing',
|
|
222
|
+
HELIX_TEST_ABSLOG_CONTENT: 'LogPython: Error: Unable to load Unreal asset — this is the real engine log, not stdout',
|
|
223
|
+
});
|
|
224
|
+
assert.equal(result.status, 1);
|
|
225
|
+
assert.match(result.stderr, /did not produce the complete reviewed export set/);
|
|
226
|
+
assert.match(result.stderr, /Unreal Editor engine log/);
|
|
227
|
+
assert.match(result.stderr, /Unable to load Unreal asset — this is the real engine log, not stdout/);
|
|
228
|
+
});
|
|
229
|
+
|
|
174
230
|
test('rejects missing and empty export files', async (t) => {
|
|
175
231
|
for (const outputKind of ['missing', 'empty']) {
|
|
176
232
|
await t.test(outputKind, () => {
|
|
@@ -272,3 +328,15 @@ test('does not walk into Binaries/Intermediate/Saved/DerivedDataCache when findi
|
|
|
272
328
|
const response = JSON.parse(result.stdout);
|
|
273
329
|
assert.equal(response.artifacts[0].kind, 'format.fbx');
|
|
274
330
|
});
|
|
331
|
+
|
|
332
|
+
test('accepts a material sidecar texture binding that records flipGreenChannel', () => {
|
|
333
|
+
// export_skeletal_mesh.py (texture_color_space) has recorded flipGreenChannel for every
|
|
334
|
+
// texture since the "Flip Green Channel" DirectX/OpenGL convention was added, but this
|
|
335
|
+
// handler's own sidecar validator never learned the key — every real export failed with
|
|
336
|
+
// "colorSpace contains unsupported metadata" until now.
|
|
337
|
+
const entry = fixture();
|
|
338
|
+
const result = run(entry, { HELIX_TEST_SIDECAR_KIND: 'flip-green' });
|
|
339
|
+
assert.equal(result.status, 0, result.stderr);
|
|
340
|
+
const sidecar = JSON.parse(readFileSync(join(entry.output, 'base-male.materials.json'), 'utf8'));
|
|
341
|
+
assert.equal(sidecar.materials[0].parameters.textures.BaseColor.colorSpace.flipGreenChannel, true);
|
|
342
|
+
});
|
package/dist/bridge/execute.js
CHANGED
|
@@ -89,10 +89,13 @@ async function importWithBridge(source, options = {}) {
|
|
|
89
89
|
let removeSignalCleanup = () => undefined;
|
|
90
90
|
let published = false;
|
|
91
91
|
let outputs = [];
|
|
92
|
+
const keepStage = options.keepStage === true || process.env.HELIX_BRIDGE_KEEP_STAGE === '1';
|
|
92
93
|
try {
|
|
93
94
|
reservation = await (0, outputReservation_1.acquireOutputReservation)(reservationPath, reservationRecord);
|
|
94
95
|
removeSignalCleanup = (0, outputReservation_1.installSignalCleanup)(reservationRecord, reservationPath, reservation, (signal) => (0, externalExecution_1.terminateActiveExternalProcesses)(`Bridge import interrupted by ${signal}`));
|
|
95
96
|
await (0, promises_1.mkdir)(transactionDir);
|
|
97
|
+
if (keepStage)
|
|
98
|
+
options.onProgress?.(`debug: bridge stage will be kept at ${transactionDir} if this import fails`);
|
|
96
99
|
const packageDir = (0, node_path_1.join)(transactionDir, 'package');
|
|
97
100
|
const workingDir = (0, node_path_1.join)(transactionDir, 'work');
|
|
98
101
|
await (0, promises_1.mkdir)(packageDir, { recursive: true });
|
|
@@ -187,8 +190,14 @@ async function importWithBridge(source, options = {}) {
|
|
|
187
190
|
}
|
|
188
191
|
finally {
|
|
189
192
|
removeSignalCleanup();
|
|
190
|
-
if (!published)
|
|
191
|
-
|
|
193
|
+
if (!published) {
|
|
194
|
+
if (keepStage) {
|
|
195
|
+
options.onProgress?.(`debug: bridge stage kept for inspection: ${transactionDir}`);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
await (0, promises_1.rm)(transactionDir, { recursive: true, force: true });
|
|
199
|
+
}
|
|
200
|
+
}
|
|
192
201
|
if (reservation)
|
|
193
202
|
await reservation.close().catch(() => undefined);
|
|
194
203
|
await (0, outputReservation_1.removeOwnedReservation)(reservationPath, reservationRecord.reservationId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/bridge/execute.ts"],"names":[],"mappings":";;;AAwEA,
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/bridge/execute.ts"],"names":[],"mappings":"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"}
|
package/dist/bridge/types.d.ts
CHANGED
|
@@ -222,6 +222,15 @@ export interface BridgeImportOptions extends BridgePlanOptions {
|
|
|
222
222
|
expectedPlanKey?: string;
|
|
223
223
|
approvedPermissions?: BridgePermission[];
|
|
224
224
|
onProgress?: (message: string) => void;
|
|
225
|
+
/**
|
|
226
|
+
* Preserve the `.{output}.bridge-stage-<uuid>/` transaction directory (raw
|
|
227
|
+
* step outputs, snapshots, and any external-tool working files) after a
|
|
228
|
+
* failed import instead of deleting it. Also honored via the
|
|
229
|
+
* `HELIX_BRIDGE_KEEP_STAGE=1` environment variable. Debug-only: never set
|
|
230
|
+
* this for a normal import, since a kept stage is not cleaned up by Bridge
|
|
231
|
+
* and accumulates on disk across retries.
|
|
232
|
+
*/
|
|
233
|
+
keepStage?: boolean;
|
|
225
234
|
}
|
|
226
235
|
export interface BridgeImportResult {
|
|
227
236
|
plan: BridgePlan;
|
package/dist/index.js
CHANGED
|
@@ -262,6 +262,7 @@ bridge
|
|
|
262
262
|
.option('--expect-plan-key <sha256>', 'execute only if the freshly resolved plan has this exact key')
|
|
263
263
|
.option('--allow-permission <permissions...>', 'permissions approved for community/local plugins; repeat or comma-separate')
|
|
264
264
|
.option('--dry-run', 'plan only; write and execute nothing')
|
|
265
|
+
.option('--keep-stage', 'debug only: preserve the .bridge-stage-<uuid> transaction directory on failure instead of deleting it (also HELIX_BRIDGE_KEEP_STAGE=1)')
|
|
265
266
|
.option('--json', 'print the machine-readable result')
|
|
266
267
|
.action(async (source, opts) => {
|
|
267
268
|
try {
|
|
@@ -280,6 +281,7 @@ bridge
|
|
|
280
281
|
expectedPlanKey: opts.expectPlanKey,
|
|
281
282
|
approvedPermissions: bridgePermissions(opts.allowPermission),
|
|
282
283
|
dryRun: opts.dryRun,
|
|
284
|
+
keepStage: opts.keepStage,
|
|
283
285
|
onProgress: (message) => console.error(` ${message}`),
|
|
284
286
|
});
|
|
285
287
|
if (opts.json)
|