fix(browser): retain module resolver cleanup ownership

Serialize resolution with shutdown, retain the owned browser after close failures, and retry cleanup before another launch. Wire cleanup through the shared service and CLI/MCP lifecycles, preserving primary failures and completed native reports alongside cleanup diagnostics.

Separate the browser resolution workflow from lifecycle ownership. Validation: seven resolver source tests, eleven application tests, MCP shutdown retry, public CLI parity, and full static/architecture checks passed. Real Chromium behavior remains unverified.
This commit is contained in:
morluto
2026-10-12 04:44:25 +08:00
parent c2b56e3e1c
commit a82e37c806
7 changed files with 441 additions and 198 deletions
+32 -22
View File
@@ -42,29 +42,39 @@ export const registerWebModuleCommands = (
.describe("HTTP(S) import-map base URL"),
}),
run: ({ args, options }) =>
withCommandCancellation((signal) =>
logCliCommand(logger, CLI_COMMANDS.traceWebModuleImports, async () => {
const result = await service.trace(
{
manifest_path: args.manifestPath,
script_index: args.scriptIndex,
...(options.importerUrl === undefined
? {}
: { importer_url: options.importerUrl }),
...(options.importMapPath === undefined &&
options.importMapBaseUrl === undefined
? {}
: {
import_map: {
path: options.importMapPath,
base_url: options.importMapBaseUrl,
},
}),
withCommandCancellation(async (signal) => {
try {
return await logCliCommand(
logger,
CLI_COMMANDS.traceWebModuleImports,
async () => {
const result = await service.trace(
{
manifest_path: args.manifestPath,
script_index: args.scriptIndex,
...(options.importerUrl === undefined
? {}
: { importer_url: options.importerUrl }),
...(options.importMapPath === undefined &&
options.importMapBaseUrl === undefined
? {}
: {
import_map: {
path: options.importMapPath,
base_url: options.importMapBaseUrl,
},
}),
},
{ signal },
);
return result.ok
? result.value
: projectAnalysisError(result.error);
},
{ signal },
);
return result.ok ? result.value : projectAnalysisError(result.error);
}),
),
} finally {
await service.close();
}
}),
});
};