Files
rea/src/cli/sourceToBundleCommand.ts
T

78 lines
3.2 KiB
TypeScript

import { z } from "incur";
import type { Logger } from "pino";
import type { CliInstance } from "./types.js";
import { CLI_COMMANDS } from "../cliCommandNames.js";
import { parseCliJsonInput } from "../cliJsonInput.js";
import { logCliCommand } from "../cliLogging.js";
import { compareSourceToBundleCliInputSchema } from "../contracts/javascript/applicationWorkflowInputContracts.js";
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
import { ArtifactResourceScope } from "../artifacts/ArtifactResourceScope.js";
import { withCommandCancellation } from "./commandCancellation.js";
import { finishAnalysisCommand } from "./finishAnalysisCommand.js";
/** CLI file transport delegates graph authentication and comparison to the same owners as MCP. */
export const registerSourceToBundleCommand = (
cli: CliInstance,
logger: Logger,
): void => {
const name = CLI_COMMANDS.compareSourceToBundle;
cli.command(name, {
description:
"Compare historical source (inline graph or reference {kind:file,path}) with authenticated application Evidence. Save the complete JSON to query with inspect-analysis-view.",
args: z.object({
inputJson: z.string().describe("Inline workflow JSON or JSON file path"),
}),
run: ({ args }) =>
withCommandCancellation((signal) =>
logCliCommand(logger, name, async () => {
const input = await parseCliJsonInput(args.inputJson, name, signal);
if (!input.ok) return input.error;
const parsed = compareSourceToBundleCliInputSchema.safeParse(
input.value,
);
if (!parsed.success)
return {
error: "Application workflow failed",
...projectAnalysisError(
analysisInputErrorFromIssues(
name,
parsed.error.issues,
input.value,
),
),
};
const resources = new ArtifactResourceScope();
const result = await finishAnalysisCommand(
async () => {
const { resolveSourceToBundleReference } =
await import("../application/javascript/SourceToBundleReference.js");
const reference = await resolveSourceToBundleReference(
parsed.data.reference,
signal,
resources,
);
if (!reference.ok) return reference;
const { compareSourceToBundleEvidence } =
await import("../application/javascript/JavaScriptApplicationWorkflowService.js");
const compared = compareSourceToBundleEvidence({
...reference.value,
application: parsed.data.application,
});
return compared.ok
? { ok: true, value: compared.value.evidence }
: compared;
},
resources,
"javascript-application-workflow",
"compare_source_to_bundle",
signal,
);
return "evidence_id" in result
? result
: { error: "Application workflow failed", ...result };
}),
),
});
};