feat(cli): accept JavaScript source selections from a JSON array or file (#5029)

* feat(cli): accept JavaScript source selections from a JSON array or file

Add --source-paths-json to analyze and analyze-javascript-application.
It takes an inline JSON array or a JSON file path of exact inventoried
paths and appends them after any --source-path values, so a long
selection no longer has to fit on one command line (cmd.exe through npx
on Windows stops at 8,191 characters). Entries stay artifact-relative and
go through the existing source_paths validation; the native lane rejects
the option like --source-path.

Refs #4987

* fix(cli): cancel --source-paths-json file reads with the command

Pass the command's abort signal through parseCliJsonInput to
readJsonInputFile, so SIGINT/SIGTERM stop a selection-file read instead
of waiting for it to finish. A cancelled read now propagates its abort
rather than being reported as a file read failure.

* test(cli): preserve ASAR identity for JSON file selections

* docs(cli): record source-selection task costs and identity verification

---------

Co-authored-by: KJLavender <KJLavender@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
This commit is contained in:
KAI-CHIEH YANG
2026-10-24 12:32:41 +08:00
committed by GitHub
parent ace47789a8
commit e5965adb29
9 changed files with 352 additions and 16 deletions
+40
View File
@@ -8,6 +8,46 @@ import { analysisErrorWithCleanupFailure } from "../domain/analysisErrorCleanup.
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
import type { JsonValue } from "../domain/jsonValue.js";
import { ProviderCleanupError } from "../domain/providerCleanupError.js";
import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
import { javaScriptSourcePathsSchema } from "../domain/javascript/javascriptSourceSelection.js";
import { parseCliJsonInput } from "../cliJsonInput.js";
const OPERATION = "analyze_javascript_application";
/**
* Combine repeated `--source-path` values with `--source-paths-json`, an inline
* JSON array or a JSON file. A file keeps large selections below the host
* command-line limit; entries remain exact application-relative paths and are
* not resolved against the working directory.
*/
export const cliJavaScriptSourcePaths = async (
sourcePath: readonly string[] | undefined,
sourcePathsJson: string | undefined,
signal?: AbortSignal,
): Promise<
| { readonly ok: true; readonly value: readonly string[] | undefined }
| { readonly ok: false; readonly error: JsonValue }
> => {
if (sourcePathsJson === undefined) return { ok: true, value: sourcePath };
const input = await parseCliJsonInput(sourcePathsJson, OPERATION, signal);
if (!input.ok) return input;
const parsed = javaScriptSourcePathsSchema.safeParse(input.value);
if (!parsed.success)
return {
ok: false,
error: cliError(
analysisInputErrorFromIssues(
OPERATION,
parsed.error.issues.map((issue) => ({
...issue,
path: ["source_paths_json", ...issue.path],
})),
{ source_paths_json: input.value },
),
),
};
return { ok: true, value: [...(sourcePath ?? []), ...parsed.data] };
};
/**
* One scope for every JavaScript analysis in this process. A healthy worker