Files
rea/src/cli/gpuCommands.ts
T
morluto 9d7779d365 fix(cli): validate selected local paths before resolution
Reuse the nonempty NUL-free local path contract before normalization in artifact commands, auxiliary inputs, and output destinations. Empty selections now fail at parsing instead of selecting the working directory; explicit relative paths preserve their target.

Public CLI checks cover primary and auxiliary empty paths, exact relative-file digest, explicit current-directory selection, symlink parent semantics, and environment export inputs. Correct the desktop fixture to assert the existing CLI validation envelope.
2026-10-24 07:28:09 +08:00

139 lines
5.2 KiB
TypeScript

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 { z } from "incur";
import type { Logger } from "pino";
import type { CliInstance } from "./types.js";
import { localPathStringSchema } from "../domain/localPath.js";
import { absoluteCallerPath } from "../filesystem/callerPath.js";
import { createGpuCodeObjectsService } from "../composition/gpu.js";
import { CLI_COMMANDS } from "../cliCommandNames.js";
import { logCliCommand } from "../cliLogging.js";
import { withCommandCancellation } from "./commandCancellation.js";
import {
analysisEvidenceDeliveryOptions,
deliverCliAnalysisEvidence,
} from "./analysisEvidenceDelivery.js";
/** One-shot summaries export the same complete observations used by MCP retained pages. */
export const registerGpuCommands = (cli: CliInstance, logger: Logger): void => {
cli.command(CLI_COMMANDS.inspectGpuCodeObjects, {
description:
"Inspect embedded CUDA/HIP targets and selected static kernel metadata",
args: z.object({
path: localPathStringSchema.describe(
"Local ELF/PE, CUDA fatbin, CUBIN, PTX or HIP bundle",
),
}),
options: z.object({
...analysisEvidenceDeliveryOptions,
view: z
.string()
.optional()
.describe(
"JSON GPU object/kernel/PTX page selection; requires --detail summary and --evidence_output",
),
analysis: z
.enum(["inventory", "kernels"])
.default("inventory")
.describe("Inventory GPU targets or decode selected kernel metadata"),
expected_sha256: z
.string()
.optional()
.describe("Inventory SHA-256; required with --object_ids"),
object_ids: z
.string()
.optional()
.describe("JSON array of exact object IDs to decode"),
targets: z
.string()
.optional()
.describe("JSON array of exact target declarations to decode"),
}),
run: ({ args, options }) =>
withCommandCancellation((signal) =>
logCliCommand(logger, CLI_COMMANDS.inspectGpuCodeObjects, async () => {
const selectors: Partial<
Record<"object_ids" | "targets" | "view", unknown>
> = {};
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`,
},
],
),
);
}
selectors[name] = decoded.value;
}
const rawInput = {
path: absoluteCallerPath(args.path),
analysis: options.analysis,
...(options.expected_sha256 === undefined
? {}
: { expected_sha256: options.expected_sha256 }),
...selectors,
detail: options.detail,
};
const selected = inspectGpuCodeObjectsInputSchema.safeParse(rawInput);
if (!selected.success)
return projectAnalysisError(
analysisInputErrorFromIssues(
"inspect_gpu_code_objects",
selected.error.issues,
rawInput,
),
);
const service = createGpuCodeObjectsService();
return deliverCliAnalysisEvidence({
run: () =>
service.inspect(
{
path: selected.data.path,
analysis: selected.data.analysis,
...(selected.data.expected_sha256 === undefined
? {}
: { expected_sha256: selected.data.expected_sha256 }),
...(selected.data.object_ids === undefined
? {}
: { object_ids: selected.data.object_ids }),
...(selected.data.targets === undefined
? {}
: { targets: selected.data.targets }),
detail: "complete",
},
{ signal },
),
service,
providerId: "gpu-code-objects",
operation: "inspect_gpu_code_objects",
signal,
detail: options.detail,
evidenceOutput: options.evidence_output,
...(selected.data.view === undefined
? {}
: {
view: {
kind: "gpu-code-objects" as const,
...selected.data.view,
},
}),
});
}),
),
});
};