refactor: consolidate shared analysis boundaries (#10293)

This commit is contained in:
morluto authored and GitHub committed 2026-11-12 22:05:32 -05:00
1 parent 6878a84796
commit c836f57b7d
70 files changed
+1240 -1131

No files matched your search

+9 -14
View File
@@ -18,6 +18,7 @@ import type { AnalysisError } from "../domain/analysisErrorBase.js";
import { redactExplicitFailure } from "../domain/explicitSensitiveFailure.js";
import { err, ok, type Result } from "../domain/result.js";
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
import { parseCliJsonOption } from "./cliJsonOption.js";
import {
createEvidenceBundle,
createImmutableEvidenceBundle,
@@ -102,20 +103,14 @@ export const parseCliAnalysisEvidenceDelivery = <
Delivery & { readonly evidenceOutput: string | undefined },
AnalysisError
> => {
let view: unknown;
try {
view = options.view === undefined ? undefined : JSON.parse(options.view);
} catch (cause) {
return err(
new AnalysisInputError(operation, { cause }, [
{
path: ["view"],
reason: "invalid_format",
message: "view must be valid JSON",
},
]),
);
}
const decoded = parseCliJsonOption(
operation,
"view",
options.view,
"view must be valid JSON",
);
if (!decoded.ok) return decoded;
const view = decoded.value;
const raw = {
detail: options.detail,
...(view === undefined ? {} : { view }),
+9 -16
View File
@@ -17,7 +17,7 @@ import {
} from "./analysisEvidenceDelivery.js";
import { androidPackageDeliverySchema } from "../domain/android/androidPackageQuery.js";
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
import { parseCliJsonOption } from "./cliJsonOption.js";
import { parseAnalysisInput } from "../application/AnalysisInput.js";
import { androidJniSelectionSchema } from "../domain/android/androidJniBindings.js";
import { androidJniDeliverySchema } from "../domain/android/androidJniQuery.js";
@@ -105,21 +105,14 @@ export const registerAndroidCommands = (
androidJniDeliverySchema,
);
if (!delivery.ok) return projectAnalysisError(delivery.error);
let query: unknown = {};
try {
if (options.query !== undefined)
query = JSON.parse(options.query);
} catch (cause: unknown) {
return projectAnalysisError(
new AnalysisInputError(operation, { cause }, [
{
path: ["query"],
reason: "invalid_format",
message: "query must be a JSON selection object.",
},
]),
);
}
const decoded = parseCliJsonOption(
operation,
"query",
options.query,
"query must be a JSON selection object.",
);
if (!decoded.ok) return projectAnalysisError(decoded.error);
const query = decoded.value === undefined ? {} : decoded.value;
const selected = parseAnalysisInput(
operation,
query,
+8 -20
View File
@@ -1,12 +1,11 @@
import { parseCliJsonOption } from "./cliJsonOption.js";
import { z } from "incur";
import type { Logger } from "pino";
import { APK_SIGNATURE_PROVIDER_IDENTITY } from "../apkSignature/ApkSignatureRelease.js";
import { apkSignatureModule } from "../composition/apkSignature.js";
import { inspectApkSignatureInputSchema } from "../domain/apkSignature/apkSignatureQuery.js";
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
import { safeParseJson } from "../domain/safeJson.js";
import { logCliCommand } from "../cliLogging.js";
import { localPathStringSchema } from "../domain/localPath.js";
import { absoluteCallerPath } from "../filesystem/callerPath.js";
@@ -41,24 +40,13 @@ export const registerApkSignatureCommands = (
run: ({ args, options }) =>
withCommandCancellation((signal) =>
logCliCommand(logger, apkSignatureModule.cliCommand, async () => {
const decoded =
options.view === undefined
? { ok: true as const, value: undefined }
: safeParseJson(options.view);
if (!decoded.ok)
return projectAnalysisError(
new AnalysisInputError(
"inspect_apk_signature",
{ cause: decoded.cause },
[
{
path: ["view"],
reason: "invalid_format",
message: "view must be a JSON APK signature selection",
},
],
),
);
const decoded = parseCliJsonOption(
"inspect_apk_signature",
"view",
options.view,
"view must be a JSON APK signature selection",
);
if (!decoded.ok) return projectAnalysisError(decoded.error);
const input = inspectApkSignatureInputSchema.safeParse({
path: absoluteCallerPath(args.path),
detail: options.detail,
+21
View File
@@ -0,0 +1,21 @@
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
import { err, ok, type Result } from "../domain/result.js";
import { safeParseJson } from "../domain/safeJson.js";
/** Decode one named CLI option before using the selected inputs. */
export const parseCliJsonOption = (
operation: string,
name: string,
text: string | undefined,
message: string,
): Result<unknown, AnalysisInputError> => {
if (text === undefined) return ok(undefined);
const parsed = safeParseJson(text);
return parsed.ok
? parsed
: err(
new AnalysisInputError(operation, { cause: parsed.cause }, [
{ path: [name], reason: "invalid_format", message },
]),
);
};
+8 -18
View File
@@ -1,8 +1,7 @@
import { inspectGpuCodeObjectsInputSchema } from "../domain/gpu/gpuCodeObjects.js";
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
import { safeParseJson } from "../domain/safeJson.js";
import { parseCliJsonOption } from "./cliJsonOption.js";
import { z } from "incur";
import type { Logger } from "pino";
import type { CliInstance } from "./types.js";
@@ -61,22 +60,13 @@ export const registerGpuCommands = (cli: CliInstance, logger: Logger): void => {
for (const name of ["object_ids", "targets", "view"] as const) {
const value = options[name];
if (value === undefined) continue;
const decoded = safeParseJson(value);
if (!decoded.ok) {
return projectAnalysisError(
new AnalysisInputError(
"inspect_gpu_code_objects",
{ cause: decoded.cause },
[
{
path: [name],
reason: "invalid_format",
message: `${name} must be valid JSON`,
},
],
),
);
}
const decoded = parseCliJsonOption(
"inspect_gpu_code_objects",
name,
value,
`${name} must be valid JSON`,
);
if (!decoded.ok) return projectAnalysisError(decoded.error);
selectors[name] = decoded.value;
}
const rawInput = {
+8 -21
View File
@@ -1,8 +1,7 @@
import { parseCliJsonOption } from "./cliJsonOption.js";
import { inspectModelArtifactInputSchema } from "../domain/model/modelArtifactQuery.js";
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
import { safeParseJson } from "../domain/safeJson.js";
import { z } from "incur";
import type { Logger } from "pino";
import type { CliInstance } from "./types.js";
@@ -48,25 +47,13 @@ export const registerModelCommands = (
run: ({ args, options }) =>
withCommandCancellation((signal) =>
logCliCommand(logger, CLI_COMMANDS.inspectModelArtifact, async () => {
const decoded =
options.view === undefined
? { ok: true as const, value: undefined }
: safeParseJson(options.view);
if (!decoded.ok) {
return projectAnalysisError(
new AnalysisInputError(
"inspect_model_artifact",
{ cause: decoded.cause },
[
{
path: ["view"],
reason: "invalid_format",
message: "view must be a JSON model page selection",
},
],
),
);
}
const decoded = parseCliJsonOption(
"inspect_model_artifact",
"view",
options.view,
"view must be a JSON model page selection",
);
if (!decoded.ok) return projectAnalysisError(decoded.error);
const view = decoded.value;
const selected = inspectModelArtifactInputSchema.safeParse({
path: absoluteCallerPath(args.path),
+8 -21
View File
@@ -1,3 +1,4 @@
import { parseCliJsonOption } from "./cliJsonOption.js";
import { z } from "incur";
import { producerLimitsOption } from "./producerLimitsOption.js";
import { rustProducerLimitsSchema } from "../domain/rust/rustResourceLimits.js";
@@ -12,9 +13,7 @@ import {
} from "./analysisEvidenceDelivery.js";
import { inspectRustBinaryRequestSchema } from "../domain/rust/rustBinaryQuery.js";
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
import { safeParseJson } from "../domain/safeJson.js";
import type { Logger } from "pino";
import type { CliInstance } from "./types.js";
import { withCommandCancellation } from "./commandCancellation.js";
@@ -62,25 +61,13 @@ export const registerRustCommands = (
run: ({ args, options }) =>
withCommandCancellation((signal) =>
logCliCommand(logger, CLI_COMMANDS.inspectRustBinary, async () => {
const decoded =
options.view === undefined
? { ok: true as const, value: undefined }
: safeParseJson(options.view);
if (!decoded.ok) {
return projectAnalysisError(
new AnalysisInputError(
"inspect_rust_binary",
{ cause: decoded.cause },
[
{
path: ["view"],
reason: "invalid_format",
message: "view must be a JSON package or edge selection",
},
],
),
);
}
const decoded = parseCliJsonOption(
"inspect_rust_binary",
"view",
options.view,
"view must be a JSON package or edge selection",
);
if (!decoded.ok) return projectAnalysisError(decoded.error);
const view = decoded.value;
const input = inspectRustBinaryRequestSchema.safeParse({
path: absoluteCallerPath(args.path),