2026-10-27 09:16:02 +08:00
import { projectCliAnalysisResult } from "./projectCliAnalysisResult.js" ;
2026-10-22 02:45:50 +08:00
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 ;
2026-10-23 09:07:43 +08:00
const { compareSourceToBundleEvidence } =
2026-10-22 02:45:50 +08:00
await import ( "../application/javascript/JavaScriptApplicationWorkflowService.js" );
2026-10-23 09:07:43 +08:00
const compared = compareSourceToBundleEvidence ({
2026-10-22 02:45:50 +08:00
... reference . value ,
application : parsed.data.application ,
});
2026-10-23 09:07:43 +08:00
return compared . ok
? { ok : true , value : compared.value.evidence }
: compared ;
2026-10-22 02:45:50 +08:00
},
resources ,
"javascript-application-workflow" ,
"compare_source_to_bundle" ,
signal ,
);
2026-10-27 09:16:02 +08:00
return result . ok
? result . value
: { error : "Application workflow failed" , ... result . error };
2026-10-22 02:45:50 +08:00
}),
),
});
};