* fix(cli): exclude declared sensitive values from parser diagnostics Incur rejects malformed command tokens and output-flag values before the web capture service applies --sensitive-value declarations, so its diagnostics repeated declared literals. Read declarations from the tokens Incur leaves for command parsing, independently of parse success. Commands accepting the option get an outermost middleware that excludes declarations from parse, validation and thrown failures while keeping type, code and exit status. Rejected --format/--token-limit/--token-offset values are replaced by a literal-free value Incur still rejects. The option definition and the Incur builtin-flag rules now have one owner each. Fixes #6252 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(cli): redact whole rejected output-flag diagnostics Incur builds its rejected --format/--token-limit/--token-offset message from fixed text and the value, outside any middleware. Substituting only the value left declarations that match the fixed text, such as "token" in "--token-limit", in the diagnostic. Report that first rejection at the serve boundary instead, redacting the whole message as parser failures are, while keeping the UNKNOWN code and Incur's toon or TTY rendering. Incur's message is now mirrored beside its acceptance rule, and the value-substitution path is removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
179 lines
9.0 KiB
TypeScript
179 lines
9.0 KiB
TypeScript
import { registerGpuCommands } from "./cli/gpuCommands.js";
|
|
import { registerNativeFunctionMatchingCommands } from "./cli/nativeFunctionMatchingCommands.js";
|
|
import { registerCaptureCommands } from "./cli/captureCommands.js";
|
|
import { registerSignalCommands } from "./cli/signalCommands.js";
|
|
import { registerWasmCommands } from "./cli/wasmCommands.js";
|
|
import { snapshotEnvironment } from "./process/snapshotEnvironment.js";
|
|
import { createDirectAnalysis } from "./composition/directAnalysis.js";
|
|
import { registerEvmCommands } from "./cli/evmCommands.js";
|
|
import { registerDesktopApplicationCommands } from "./cli/desktopApplicationCommands.js";
|
|
import { registerGoCommands } from "./cli/goCommands.js";
|
|
import { registerModelCommands } from "./cli/modelCommands.js";
|
|
import { registerIl2cppCommands } from "./cli/il2cppCommands.js";
|
|
import { registerRustCommands } from "./cli/rustCommands.js";
|
|
import { registerSqliteCommands } from "./cli/sqliteCommands.js";
|
|
import { registerAnalysisViewCommands } from "./cli/analysisViewCommands.js";
|
|
import { registerBinaryDiagnosticsCommands } from "./cli/binaryDiagnosticsCommands.js";
|
|
import { registerFridaCommands } from "./cli/fridaCommands.js";
|
|
import type { FridaInstrumentationPort } from "./application/frida/FridaInstrumentationPort.js";
|
|
import { Cli } from "incur";
|
|
import { normalizeCliArguments } from "./cliOutput.js";
|
|
|
|
import { createLogger, parseLogLevel } from "./logger.js";
|
|
import { projectAnalysisError } from "./domain/analysisErrorProjection.js";
|
|
import { PRODUCT_IDENTITY } from "./identity.js";
|
|
import { npxRegistrationCommand } from "./application/ClientRegistrationIdentity.js";
|
|
import { registerSetupCommands } from "./cli/setupCommands.js";
|
|
import { registerCoreAnalysisCommands } from "./cli/coreAnalysisCommands.js";
|
|
import { registerUtilityCommands } from "./cli/utilityCommands.js";
|
|
import { registerArtifactCommands } from "./cli/artifactCommands.js";
|
|
import { registerManagedCommands } from "./cli/managedCommands.js";
|
|
import { registerFirmwareCommands } from "./cli/firmwareCommands.js";
|
|
import { registerAndroidCommands } from "./cli/androidCommands.js";
|
|
import { registerApktoolCommands } from "./cli/apktoolCommands.js";
|
|
import { registerPcapCommands } from "./cli/pcapCommands.js";
|
|
import { registerFlutterCommands } from "./cli/flutterCommands.js";
|
|
import { registerJebCommands } from "./cli/jebCommands.js";
|
|
import { registerAdbCommands } from "./cli/adbCommands.js";
|
|
import { registerEvidenceCommands } from "./cliEvidenceCommands.js";
|
|
import { registerEnvironmentCommands } from "./cli/environmentCommands.js";
|
|
import { registerProcessCommands } from "./cli/processCommands.js";
|
|
import { registerBrowserCommands } from "./cli/browserCommands.js";
|
|
import { registerWebScriptCommands } from "./cli/webScriptCommands.js";
|
|
import { registerWebModuleCommands } from "./cli/webModuleCommands.js";
|
|
import { registerWebSourceLocationCommands } from "./cli/webSourceLocationCommands.js";
|
|
import { registerWebRuntimeCommands } from "./cli/webRuntimeCommands.js";
|
|
import { registerWebNetworkCaptureCommands } from "./cli/webNetworkCaptureCommands.js";
|
|
import { registerJavaScriptRecoveryCommands } from "./cli/javascriptRecoveryCommands.js";
|
|
import { registerAdvancedBrowserCommands } from "./cli/browserAdvancedCommands.js";
|
|
import { registerBrowserScenarioCommands } from "./cliBrowserScenarioCommands.js";
|
|
import { registerElectronCommands } from "./cli/electronCommands.js";
|
|
import { registerJavaScriptRuntimeObservationCommands } from "./cliJavaScriptRuntimeCommands.js";
|
|
import { registerApplicationCommands } from "./cli/applicationCommands.js";
|
|
import { presentOmittableDefaults } from "./cli/omittableDefaults.js";
|
|
import type { CliInstance } from "./cli/types.js";
|
|
import {
|
|
streamCliCommandResults,
|
|
type CliResultOutput,
|
|
} from "./cli/cliResultOutput.js";
|
|
import { registerReverseEngineeringCommands } from "./cli/reverseEngineeringCommands.js";
|
|
import { registerCutterCommands } from "./cli/cutterCommands.js";
|
|
import { excludeDeclaredSensitiveArguments } from "./cli/explicitSensitiveArguments.js";
|
|
|
|
export { closeCliJavaScriptResources } from "./cli/javascriptApplicationAnalysis.js";
|
|
|
|
/**
|
|
* Describe CLI settings that are invalid before any command runs, as MCP does.
|
|
* Keep this aligned with PROCESS_START_CONFIGURATION_SETTINGS.
|
|
*/
|
|
export const cliConfigurationError = (
|
|
selectedEnvironment: Readonly<Record<string, string | undefined>>,
|
|
): string | undefined => {
|
|
const value = selectedEnvironment.REA_LOG_LEVEL;
|
|
if (value === undefined) return undefined;
|
|
const level = parseLogLevel(value);
|
|
return level.ok ? undefined : projectAnalysisError(level.error).message;
|
|
};
|
|
|
|
/**
|
|
* Build the one-shot Incur CLI without starting Hopper at import time.
|
|
* Analysis commands acquire and close their own sessions; bare `mcp` and
|
|
* `--mcp` are intercepted by the executable dispatcher before this module loads.
|
|
*/
|
|
export const createCli = (
|
|
selectedEnvironment: Readonly<
|
|
Record<string, string | undefined>
|
|
> = process.env,
|
|
resultOutput?: CliResultOutput,
|
|
fridaInstrumentation?: FridaInstrumentationPort,
|
|
): CliInstance => {
|
|
const environment = snapshotEnvironment(selectedEnvironment);
|
|
const analysis = createDirectAnalysis(environment);
|
|
// The executable reports an invalid level before every command except doctor.
|
|
// Doctor keeps going so its readiness report can name REA_LOG_LEVEL.
|
|
const level =
|
|
environment.REA_LOG_LEVEL === undefined
|
|
? undefined
|
|
: parseLogLevel(environment.REA_LOG_LEVEL);
|
|
const logger = createLogger(
|
|
"cli",
|
|
level?.ok === true ? level.value : "silent",
|
|
);
|
|
const cli = Cli.create(PRODUCT_IDENTITY.cliBinary, {
|
|
version: PRODUCT_IDENTITY.packageVersion,
|
|
description: "Reverse engineer anything from your terminal or agent.",
|
|
mcp: {
|
|
command: npxRegistrationCommand().join(" "),
|
|
instructions:
|
|
"Ask what software, artifact, protocol, or behavior the user wants to understand, then choose the available investigation capabilities that can produce evidence.",
|
|
},
|
|
sync: false,
|
|
update: {
|
|
// Incur's update:false only suppresses notices. Reject its explicit
|
|
// installer so ambiguous flags cannot bypass REA's verified workflow.
|
|
install: () => {
|
|
throw new Error(
|
|
"Use 'rea update' to update the identified installation. The '--update' alias accepts only global output flags.",
|
|
);
|
|
},
|
|
},
|
|
});
|
|
|
|
registerSetupCommands(cli, logger, environment);
|
|
registerReverseEngineeringCommands(cli, logger, environment);
|
|
registerCutterCommands(cli, logger, environment);
|
|
registerCoreAnalysisCommands(
|
|
cli,
|
|
logger,
|
|
analysis.runDirectAnalysis,
|
|
environment,
|
|
);
|
|
registerUtilityCommands(cli, logger, environment, analysis);
|
|
registerWasmCommands(cli, logger, environment);
|
|
registerCaptureCommands(cli, logger, environment);
|
|
registerSignalCommands(cli, logger, environment);
|
|
registerEvmCommands(cli, logger, environment);
|
|
registerDesktopApplicationCommands(cli, logger);
|
|
registerGoCommands(cli, logger);
|
|
registerIl2cppCommands(cli, logger);
|
|
registerModelCommands(cli, logger);
|
|
registerGpuCommands(cli, logger);
|
|
registerRustCommands(cli, logger);
|
|
registerSqliteCommands(cli, logger, environment);
|
|
registerArtifactCommands(cli, logger, analysis.runProviderAnalysis);
|
|
registerManagedCommands(cli, logger, analysis.runProviderAnalysis);
|
|
registerAndroidCommands(cli, logger, environment);
|
|
registerApktoolCommands(cli, logger, environment);
|
|
registerPcapCommands(cli, logger, environment);
|
|
registerFlutterCommands(cli, logger);
|
|
registerJebCommands(cli, logger, environment);
|
|
registerAdbCommands(cli, logger, environment);
|
|
registerFirmwareCommands(cli, logger, environment);
|
|
registerBinaryDiagnosticsCommands(cli, logger, environment);
|
|
registerAnalysisViewCommands(cli, logger);
|
|
registerNativeFunctionMatchingCommands(cli, logger);
|
|
registerFridaCommands(cli, logger, fridaInstrumentation);
|
|
registerEvidenceCommands(cli, logger);
|
|
registerEnvironmentCommands(cli, logger, environment);
|
|
registerProcessCommands(cli, logger, environment);
|
|
registerBrowserCommands(cli, logger);
|
|
registerWebScriptCommands(cli, logger);
|
|
registerWebModuleCommands(cli, logger, environment);
|
|
registerWebSourceLocationCommands(cli, logger, environment);
|
|
registerWebRuntimeCommands(cli, logger);
|
|
registerWebNetworkCaptureCommands(cli, logger, environment);
|
|
registerJavaScriptRecoveryCommands(cli, logger, environment);
|
|
registerAdvancedBrowserCommands(cli, logger);
|
|
registerBrowserScenarioCommands(cli, logger, environment);
|
|
registerElectronCommands(cli, logger, environment);
|
|
registerJavaScriptRuntimeObservationCommands(cli, logger, environment);
|
|
registerApplicationCommands(cli, logger);
|
|
presentOmittableDefaults(cli);
|
|
if (resultOutput !== undefined) streamCliCommandResults(cli, resultOutput);
|
|
const serveDeclared = excludeDeclaredSensitiveArguments(cli);
|
|
const serve = cli.serve.bind(cli);
|
|
cli.serve = (arguments_ = process.argv.slice(2), options) =>
|
|
serveDeclared(normalizeCliArguments(arguments_), options ?? {}, serve);
|
|
return cli;
|
|
};
|