fix(publication)!: retain cleanup owners across export workflows

Require an ArtifactResourceScope for web script exports and share its lifetime with CLI or MCP shutdown. Retain setup-failed output trees in firmware and Wakaru providers. Preserve completed publications when descriptor cleanup fails, returning the full result after a successful retry or as a partial observation while cleanup remains unresolved.
This commit is contained in:
morluto
2026-10-11 05:16:42 +08:00
parent 3f8c51e9b5
commit be75ed5e4b
15 changed files with 801 additions and 166 deletions
+37 -4
View File
@@ -1,9 +1,13 @@
import { Cli, z } from "incur";
import { exportWebScripts } from "../application/WebScriptExportService.js";
import { ArtifactReaderFailure } from "../artifacts/ArtifactReader.js";
import { ArtifactResourceScope } from "../artifacts/ArtifactResourceScope.js";
import { CLI_COMMANDS } from "../cliCommandNames.js";
import { logCliCommand } from "../cliLogging.js";
import { analysisErrorWithCleanupFailure } from "../domain/analysisErrorCleanup.js";
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
import { ProviderCleanupError } from "../domain/providerCleanupError.js";
import type { Logger } from "pino";
/** Register the local captured-script export CLI workflow. */
@@ -26,10 +30,39 @@ export const registerWebScriptCommands = (
}),
run: ({ args }) =>
logCliCommand(logger, CLI_COMMANDS.exportWebScripts, async () => {
const result = await exportWebScripts({
capture_path: args.capturePath,
output_directory: args.outputDirectory,
});
const resources = new ArtifactResourceScope();
const result = await exportWebScripts(
{
capture_path: args.capturePath,
output_directory: args.outputDirectory,
},
resources,
);
try {
await resources.close();
} catch (cause: unknown) {
const cleanup = ArtifactReaderFailure.cleanupObservation(
cause,
"Web script export resources",
);
const failure = new ProviderCleanupError(
"web-script-export",
cleanup.resources,
{ reason: cleanup.reason },
{ cause, operation: "export_web_scripts" },
);
const error = result.ok
? failure
: analysisErrorWithCleanupFailure(
result.error,
failure,
"export_web_scripts",
);
return {
error: "Script export failed",
...projectAnalysisError(error),
};
}
return result.ok
? result.value
: {