react-doctor 0.9.11 → 0.9.12-dev.025d69d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +28 -1
  2. package/bin/react-doctor.js +1 -9
  3. package/dist/active-run-trace-dlIZeEvb.js +18 -0
  4. package/dist/active-scan-abort-registry-DwG6tSPy.js +28 -0
  5. package/dist/{build-section-divider-sLcWe1hO.js → build-section-divider-Rtaiowhy.js} +10 -25
  6. package/dist/{ci-DsrrD52i.js → ci-BB3u5Gt7.js} +13 -12
  7. package/dist/cli.js +84 -32
  8. package/dist/{design-CP25gyyg.js → design-DndYvifI.js} +4 -4
  9. package/dist/{devtools-DPRVRu3S.js → devtools-BiC-AP3B.js} +4 -4
  10. package/dist/{exit-gracefully-CVVkBxDS.js → exit-gracefully-DShLWQuA.js} +15 -9
  11. package/dist/get-east-asian-width-Cglw13G7.js +444 -0
  12. package/dist/{report-error-CAEixMg1.js → handle-error-D1wDDJF-.js} +18 -68
  13. package/dist/index.d.ts +70 -61
  14. package/dist/index.js +55252 -54707
  15. package/dist/{inspect-D6y8oLtg.js → inspect-FuGxonlI.js} +26 -24
  16. package/dist/{install-afMFGeTB.js → install-DMK7JRVX.js} +9 -8
  17. package/dist/{install-doctor-script-Be7Mv3-l.js → install-doctor-script-JE3JnnQc.js} +7 -449
  18. package/dist/{install-github-workflow-Dev2F6Ea.js → install-github-workflow-BdY3qY2f.js} +10 -6
  19. package/dist/{install-react-doctor-DIPVunY4.js → install-react-doctor-BMn0_WV6.js} +47 -45
  20. package/dist/{run-scan-app-BGzlyiIB.js → jsx-runtime-pWsmwZGj.js} +281 -2726
  21. package/dist/{print-branded-header-D5jLdo4p.js → print-branded-header-BmI9tLH6.js} +4 -4
  22. package/dist/project-analysis-worker.d.ts +1 -0
  23. package/dist/project-analysis-worker.js +51901 -0
  24. package/dist/prompt-runtime-scan-url-BfBBYAfw.js +240 -0
  25. package/dist/{read-object-file-CEh1CqnD.js → read-object-file-CRpKojJA.js} +4 -4
  26. package/dist/{record-metric-CJxSHfJD.js → record-metric-BM82PBSe.js} +3338 -6056
  27. package/dist/report-error-CZHQUNh4.js +64 -0
  28. package/dist/{report-workflow-result-C0jbKH8p.js → report-workflow-result-xEGmAMA7.js} +5 -5
  29. package/dist/{resolve-scope-DS7rcRRz.js → resolve-scope-Bnf4Y4EW.js} +6 -6
  30. package/dist/{rules-BJynymuU.js → rules-DzOjQMX6.js} +6 -6
  31. package/dist/run-scan-app-BV3v34-X.js +2510 -0
  32. package/dist/runtime-scan/browser-probe.iife.js +855 -0
  33. package/dist/runtime-scan-B85-DJZM.js +770 -0
  34. package/dist/sanitize-runtime-url-CPjeveTJ.js +76 -0
  35. package/dist/{scan-CgPRG6_z.js → scan-DuP6gdzt.js} +10 -22
  36. package/dist/semver-DFtnEmN-.js +3219 -0
  37. package/dist/{should-fail-scan-gate-4jf7ZRdL.js → should-fail-scan-gate-DXLurKbC.js} +199 -195
  38. package/dist/{should-skip-prompts-C78r7Ww7.js → should-skip-prompts-CQyO96OW.js} +4 -4
  39. package/dist/should-use-tui-CNPwNNtA.js +25 -0
  40. package/dist/skills/improve-threejs/SKILL.md +102 -0
  41. package/dist/skills/performance/SKILL.md +113 -0
  42. package/dist/skills/react-doctor/SKILL.md +6 -0
  43. package/dist/{unref-stdin-Dc8ipkaw.js → telemetry-runtime-DbSLLSa0.js} +57 -33
  44. package/dist/unref-stdin-BKT_s38a.js +12 -0
  45. package/dist/{version-DDrwsTas.js → version-Zw_S1mCX.js} +4 -4
  46. package/dist/{why-BRNrKY1b.js → why-B-WcOS0C.js} +4 -4
  47. package/dist/with-run-span-CVyFHX3Z.js +110 -0
  48. package/package.json +9 -12
  49. package/dist/chunk-q7NCDQ7-.js +0 -28
  50. package/dist/lsp.js +0 -81114
@@ -1,26 +1,18 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="79ca2870-c5c5-5bc1-92cd-ec761fd7f27f")}catch(e){}}();
3
- import { n as __require, r as __toESM, t as __commonJSMin } from "./chunk-q7NCDQ7-.js";
4
- import { $t as getCategoryImpact, B as isGitHookEnvironment, Cn as mapWithConcurrency, Dn as remainingDeadlineBudgetMs, I as TUI_REPORT_COMPACT_MAX_ROWS, It as calculateScore, L as TUI_REPORT_DETAIL_WIDTH_FRACTION, Mn as resolveScanTarget, Pt as buildRuleDocsUrl, Qt as getBaselineDiffPlan, S as CI_TRUST_COMPANIES, St as Reporter, Vn as yieldToEventLoop, W as isCiEnvironment, an as hasPublishedFixRecipe, bt as Progress, cn as highlighter, cr as void_, en as getChangedLineRanges, fr as succeed, ir as runPromise, n as recordDistribution, nn as getDiffInfo, or as sync, ot as GITHUB_ACTIONS_SETUP_URL, pn as isPathInsideDirectory, t as recordCount, tt as DIAGNOSTIC_CATEGORY_BUCKETS, w as METRIC } from "./record-metric-CJxSHfJD.js";
5
- import { n as registerActiveTuiRenderer, t as exitGracefully } from "./exit-gracefully-CVVkBxDS.js";
6
- import { L as cliLogger, d as stripAnsi, f as isUnicodeSupported, l as isFullWidth$1, n as findNearestPackageDirectory, p as chalk, u as isWide$1 } from "./install-doctor-script-Be7Mv3-l.js";
7
- import { i as isReactDoctorWorkflowInstalled } from "./install-github-workflow-Dev2F6Ea.js";
8
- import { r as resolveScope, s as resolveBlockingLevel, t as finalizeScope, u as toForwardSlashes } from "./resolve-scope-DS7rcRRz.js";
9
- import { A as resolveMergeBaseRef, B as buildEmptyReportMessage, C as copyToClipboard, D as deduplicateProjectScans, E as collectProjectSourceFileCounts, F as printDiagnosticsDump, G as formatLearnMoreLine, H as buildRulePriorityMap, I as formatDiagnosticSite, L as hasIncompleteScoreAnalysis, M as pluralize, N as formatElapsedTime, O as createInvocationInspect, P as printFooter, R as filterDiagnosticsByCategories, S as CLI_AGENT_BINARIES, T as buildHandoffPayload, U as buildSortedRuleGroups, V as hasLintHardFailure, W as formatFixRecipeLine, _ as resolveCliInspectOptions, a as projectManifestChanged, b as setUpGitHubActions, c as selectProjects, d as resolveProjectChangedLineRanges, f as resolveProjectDiffIncludePaths, g as resolveWorkspaceDeadCodeOwner, h as retryMissingProjectScores, l as buildCodeFrame, n as formatSkippedProjectsMessage, o as partitionProjectScanOutcomes, p as resolveProjectSourceFilePaths, r as validateIncludeUntrackedScope, s as discoverWorkspacePackages, t as shouldFailScanGate, u as resolveProjectScan, v as filterScansForSurface, w as launchCliAgent, x as detectLaunchableAgents, y as countUniqueScannedFiles, z as buildNoScoreMessage } from "./should-fail-scan-gate-4jf7ZRdL.js";
10
- import { a as recordGate, f as ONBOARDING_EVENT, n as openUrl, r as isGatePending } from "./report-workflow-result-C0jbKH8p.js";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a329e542-01f9-5ef2-a316-8873ce41d83a")}catch(e){}}();
3
+ import { i as __toESM, r as __require, t as __commonJSMin } from "./chunk-ChKA3wi6.js";
4
+ import { T as METRIC, t as recordCount } from "./record-metric-BM82PBSe.js";
5
+ import { n as registerActiveTuiRenderer, t as exitGracefully } from "./exit-gracefully-DShLWQuA.js";
6
+ import { a as chalk, i as stripAnsi, n as isFullWidth$1, r as isWide$1 } from "./get-east-asian-width-Cglw13G7.js";
11
7
  import { EventEmitter } from "node:events";
12
8
  import { execFileSync } from "node:child_process";
13
- import path from "node:path";
14
9
  import * as fs$1 from "node:fs";
15
10
  import fs from "node:fs";
16
11
  import process$1, { cwd, env } from "node:process";
17
12
  import os from "node:os";
18
13
  import { PassThrough, Stream } from "node:stream";
19
- import { performance as performance$1 } from "node:perf_hooks";
20
14
  import tty from "node:tty";
21
- import { getSkillAgentConfig } from "agent-install";
22
15
  import Yoga from "yoga-layout";
23
- import figures from "figures";
24
16
  //#region ../../node_modules/.pnpm/react@19.2.5/node_modules/react/cjs/react.production.js
25
17
  /**
26
18
  * @license React
@@ -20448,7 +20440,7 @@ if (process$1.env["DEV"] === "true") {
20448
20440
  import.meta.resolve("react-devtools-core");
20449
20441
  isDevtoolsInstalled = true;
20450
20442
  } catch {}
20451
- if (isDevtoolsInstalled) await import("./devtools-DPRVRu3S.js");
20443
+ if (isDevtoolsInstalled) await import("./devtools-BiC-AP3B.js");
20452
20444
  }
20453
20445
  const diff = (before, after) => {
20454
20446
  if (before === after) return;
@@ -20952,24 +20944,24 @@ const BEL = "\x07";
20952
20944
  const ESC = "\x1B";
20953
20945
  const BACKSLASH = "\\";
20954
20946
  const CSI = "[";
20955
- const OSC$1 = "]";
20947
+ const OSC = "]";
20956
20948
  const C1_ST = "œ";
20957
20949
  const CC_BEL = BEL.charCodeAt(0);
20958
20950
  const CC_ESC = ESC.charCodeAt(0);
20959
20951
  const CC_BACKSLASH = BACKSLASH.charCodeAt(0);
20960
20952
  const CC_CSI = CSI.charCodeAt(0);
20961
- const CC_OSC = OSC$1.charCodeAt(0);
20953
+ const CC_OSC = OSC.charCodeAt(0);
20962
20954
  const CC_C1_ST = C1_ST.charCodeAt(0);
20963
20955
  "0".charCodeAt(0);
20964
20956
  "9".charCodeAt(0);
20965
20957
  ";".charCodeAt(0);
20966
20958
  "m".charCodeAt(0);
20967
20959
  const ESCAPES = new Set([CC_ESC, 155]);
20968
- const linkCodePrefix = `${ESC}${OSC$1}8;`;
20960
+ const linkCodePrefix = `${ESC}${OSC}8;`;
20969
20961
  const linkCodePrefixCharCodes = linkCodePrefix.split("").map((char) => char.charCodeAt(0));
20970
- const linkEndCode = `${ESC}${OSC$1}8;;${BEL}`;
20971
- const linkEndCodeST = `${ESC}${OSC$1}8;;${ESC}${BACKSLASH}`;
20972
- const linkEndCodeC1ST = `${ESC}${OSC$1}8;;${C1_ST}`;
20962
+ const linkEndCode = `${ESC}${OSC}8;;${BEL}`;
20963
+ const linkEndCodeST = `${ESC}${OSC}8;;${ESC}${BACKSLASH}`;
20964
+ const linkEndCodeC1ST = `${ESC}${OSC}8;;${C1_ST}`;
20973
20965
  //#endregion
20974
20966
  //#region ../../node_modules/.pnpm/@alcalzone+ansi-tokenize@0.3.0/node_modules/@alcalzone/ansi-tokenize/build/ansiCodes.js
20975
20967
  const endCodesSet = /* @__PURE__ */ new Set();
@@ -23963,2083 +23955,6 @@ A React hook that returns the stdout stream where Ink renders your app.
23963
23955
  */
23964
23956
  const useStdout = () => (0, import_react.useContext)(StdoutContext);
23965
23957
  //#endregion
23966
- //#region src/cli/utils/get-top-error-rule-keys.ts
23967
- const getTopErrorRuleKeys = (diagnostics, limit, rulePriority) => new Set(buildSortedRuleGroups(diagnostics.filter((diagnostic) => diagnostic.severity === "error"), rulePriority).slice(0, limit).map(([ruleKey]) => ruleKey));
23968
- //#endregion
23969
- //#region src/cli/utils/compute-score-projection.ts
23970
- const computeProjectedScore = async (topErrorSource, rescoreSource, currentScore) => {
23971
- const topErrorRuleKeys = getTopErrorRuleKeys(topErrorSource, 3, buildRulePriorityMap([currentScore]));
23972
- if (topErrorRuleKeys.size === 0) return null;
23973
- const potentialScore = await calculateScore(rescoreSource.filter((diagnostic) => !topErrorRuleKeys.has(`${diagnostic.plugin}/${diagnostic.rule}`)));
23974
- if (!potentialScore || potentialScore.score <= currentScore.score) return null;
23975
- return potentialScore.score;
23976
- };
23977
- //#endregion
23978
- //#region src/cli/utils/is-share-opted-out.ts
23979
- const isShareOptedOut = (scans, flagNoScore) => Boolean(flagNoScore) || scans.some((scan) => Boolean(scan.config?.noScore) || scan.config?.share === false);
23980
- //#endregion
23981
- //#region src/cli/utils/resolve-project-tui-scan-scope.ts
23982
- const resolveProjectTuiScanScope = (input) => {
23983
- if (input.plan.scope === "full") return {};
23984
- if (input.plan.diffInfo === null) return null;
23985
- const changedSourceFiles = resolveProjectDiffIncludePaths(input.rootDirectory, input.projectDirectory, input.plan.diffInfo);
23986
- const baselineBaseFiles = input.plan.baselineDiffPlan === null ? null : resolveProjectSourceFilePaths(input.rootDirectory, input.projectDirectory, input.plan.baselineDiffPlan.baseFiles);
23987
- const baselineHeadFiles = input.plan.baselineDiffPlan === null ? null : resolveProjectSourceFilePaths(input.rootDirectory, input.projectDirectory, input.plan.baselineDiffPlan.headFiles);
23988
- const supplyChainManifestChanged = input.supplyChainEnabled && projectManifestChanged(input.rootDirectory, input.projectDirectory, input.plan.diffInfo);
23989
- const hasBaselineOnlyFiles = (baselineBaseFiles?.length ?? 0) > 0;
23990
- if (!supplyChainManifestChanged && changedSourceFiles.length === 0 && !hasBaselineOnlyFiles) return null;
23991
- const includePaths = [...changedSourceFiles];
23992
- if (includePaths.length === 0 && hasBaselineOnlyFiles) includePaths.push(...baselineBaseFiles ?? []);
23993
- if (supplyChainManifestChanged) includePaths.push("package.json");
23994
- return {
23995
- includePaths,
23996
- baseline: input.plan.baselineRef !== null && baselineBaseFiles !== null && baselineHeadFiles !== null ? {
23997
- ref: input.plan.baselineRef,
23998
- baseFiles: baselineBaseFiles,
23999
- headFiles: baselineHeadFiles
24000
- } : void 0,
24001
- changedLineRanges: input.plan.scope === "lines" && input.plan.changedLineRanges !== null ? resolveProjectChangedLineRanges(input.rootDirectory, input.projectDirectory, input.plan.changedLineRanges) : void 0,
24002
- supplyChainManifestChanged
24003
- };
24004
- };
24005
- //#endregion
24006
- //#region src/cli/utils/resolve-tui-scan-scope.ts
24007
- const resolveTuiScanScope = async (input) => {
24008
- const requestedScope = resolveScope(input.flags, input.userConfig);
24009
- const includeUntracked = input.flags.includeUntracked ?? false;
24010
- validateIncludeUntrackedScope(includeUntracked, requestedScope.scope);
24011
- const diffInfo = requestedScope.scope !== void 0 && requestedScope.scope !== "full" ? await getDiffInfo(input.directory, requestedScope.base, includeUntracked) : null;
24012
- const scope = await finalizeScope({
24013
- requested: requestedScope,
24014
- diffInfo,
24015
- skipPrompts: true,
24016
- isQuiet: false
24017
- });
24018
- let comparisonBaseRef = null;
24019
- if (scope !== "full" && diffInfo !== null && !diffInfo.isCurrentChanges) if (diffInfo.baseSha !== void 0) comparisonBaseRef = await resolveMergeBaseRef(input.directory, diffInfo.baseSha);
24020
- else if (diffInfo.diffBaseRef !== void 0) comparisonBaseRef = diffInfo.diffBaseRef;
24021
- else comparisonBaseRef = await resolveMergeBaseRef(input.directory, diffInfo.baseBranch);
24022
- const baselineRef = scope === "changed" ? comparisonBaseRef : null;
24023
- const baselineDiffPlan = baselineRef === null ? null : await getBaselineDiffPlan(input.directory, baselineRef);
24024
- const linesBaseRef = diffInfo?.isCurrentChanges ? "HEAD" : comparisonBaseRef;
24025
- const changedLineRanges = scope === "lines" && diffInfo !== null && (diffInfo.isCurrentChanges || linesBaseRef !== null) ? await getChangedLineRanges({
24026
- directory: input.directory,
24027
- baseRef: linesBaseRef ?? void 0,
24028
- files: [...diffInfo.changedFiles],
24029
- includeUntracked
24030
- }) : null;
24031
- if (scope === "lines" && changedLineRanges === null) {
24032
- cliLogger.warn("Could not determine changed lines (no base ref or git diff failed); reporting all issues in changed files.");
24033
- cliLogger.break();
24034
- }
24035
- return {
24036
- baselineDiffPlan,
24037
- baselineIntended: scope === "changed" && diffInfo !== null && !diffInfo.isCurrentChanges,
24038
- baselineRef,
24039
- changedLineRanges,
24040
- diffInfo,
24041
- scope
24042
- };
24043
- };
24044
- //#endregion
24045
- //#region src/cli/utils/select-report-diagnostics.ts
24046
- const selectReportDiagnostics = (input) => {
24047
- const surfaceDiagnostics = filterScansForSurface([input.scan], input.surface ?? "cli");
24048
- return {
24049
- diagnostics: filterDiagnosticsByCategories(surfaceDiagnostics, new Set(input.categoryFilters)),
24050
- demotedDiagnosticCount: input.scan.result.diagnostics.length - surfaceDiagnostics.length
24051
- };
24052
- };
24053
- //#endregion
24054
- //#region src/cli/utils/clamp-number.ts
24055
- const clampNumber = (value, minimum, maximum) => Math.max(minimum, Math.min(maximum, value));
24056
- //#endregion
24057
- //#region src/cli/utils/is-printable-input.ts
24058
- const isPrintableInput = (input) => input.length > 0 && [...input].every((character) => character.charCodeAt(0) >= 32);
24059
- //#endregion
24060
- //#region src/cli/utils/resolve-visible-start.ts
24061
- const resolveVisibleStart = ({ itemCount, offset, selectedIndex, viewportHeight }) => {
24062
- if (viewportHeight <= 0) return 0;
24063
- const boundedOffset = clampNumber(offset, 0, Math.max(0, itemCount - viewportHeight));
24064
- if (selectedIndex < boundedOffset) return selectedIndex;
24065
- if (selectedIndex >= boundedOffset + viewportHeight) return Math.max(0, selectedIndex - viewportHeight + 1);
24066
- return boundedOffset;
24067
- };
24068
- //#endregion
24069
- //#region src/cli/ink/hooks/use-exit-on-ctrl-c.ts
24070
- const SHOW_CURSOR = "\x1B[?25h";
24071
- const useExitOnCtrlC = (onCancel) => {
24072
- useInput((input, key) => {
24073
- if (key.ctrl && input === "c") {
24074
- onCancel?.();
24075
- recordCount(METRIC.tuiCancelled, 1, { resourceFooter: true });
24076
- process.stdin.setRawMode?.(false);
24077
- process.stdout.write(SHOW_CURSOR);
24078
- exitGracefully();
24079
- }
24080
- });
24081
- };
24082
- //#endregion
24083
- //#region src/cli/ink/hooks/use-stdout-dimensions.ts
24084
- const readDimensions = (stdout) => ({
24085
- columns: stdout?.columns ?? 80,
24086
- rows: stdout?.rows ?? 24
24087
- });
24088
- const useStdoutDimensions = () => {
24089
- const { stdout } = useStdout();
24090
- const [dimensions, setDimensions] = (0, import_react.useState)(() => readDimensions(stdout));
24091
- (0, import_react.useEffect)(() => {
24092
- if (!stdout) return;
24093
- const onResize = () => setDimensions(readDimensions(stdout));
24094
- stdout.on("resize", onResize);
24095
- return () => {
24096
- stdout.off("resize", onResize);
24097
- };
24098
- }, [stdout]);
24099
- return dimensions;
24100
- };
24101
- //#endregion
24102
- //#region src/cli/ink/lib/fuzzy-match.ts
24103
- const fuzzyMatch = (query, target) => {
24104
- if (query.length === 0) return {
24105
- score: 0,
24106
- matchedIndices: []
24107
- };
24108
- const lowerQuery = query.toLowerCase();
24109
- const lowerTarget = target.toLowerCase();
24110
- const matchedIndices = [];
24111
- let score = 0;
24112
- let queryIndex = 0;
24113
- let previousMatchIndex = Number.NEGATIVE_INFINITY;
24114
- for (let targetIndex = 0; targetIndex < lowerTarget.length && queryIndex < lowerQuery.length; targetIndex++) {
24115
- if (lowerTarget[targetIndex] !== lowerQuery[queryIndex]) continue;
24116
- matchedIndices.push(targetIndex);
24117
- if (targetIndex === previousMatchIndex + 1) score += 5;
24118
- const previousCharacter = target[targetIndex - 1];
24119
- if (targetIndex === 0 || previousCharacter === "-" || previousCharacter === "_" || previousCharacter === "/" || previousCharacter === " ") score += 10;
24120
- previousMatchIndex = targetIndex;
24121
- queryIndex++;
24122
- }
24123
- if (queryIndex < lowerQuery.length) return null;
24124
- score -= matchedIndices[0] * 1;
24125
- return {
24126
- score,
24127
- matchedIndices
24128
- };
24129
- };
24130
- //#endregion
24131
- //#region ../../node_modules/.pnpm/react@19.2.5/node_modules/react/cjs/react-jsx-runtime.production.js
24132
- /**
24133
- * @license React
24134
- * react-jsx-runtime.production.js
24135
- *
24136
- * Copyright (c) Meta Platforms, Inc. and affiliates.
24137
- *
24138
- * This source code is licensed under the MIT license found in the
24139
- * LICENSE file in the root directory of this source tree.
24140
- */
24141
- var require_react_jsx_runtime_production = /* @__PURE__ */ __commonJSMin(((exports) => {
24142
- var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment");
24143
- function jsxProd(type, config, maybeKey) {
24144
- var key = null;
24145
- void 0 !== maybeKey && (key = "" + maybeKey);
24146
- void 0 !== config.key && (key = "" + config.key);
24147
- if ("key" in config) {
24148
- maybeKey = {};
24149
- for (var propName in config) "key" !== propName && (maybeKey[propName] = config[propName]);
24150
- } else maybeKey = config;
24151
- config = maybeKey.ref;
24152
- return {
24153
- $$typeof: REACT_ELEMENT_TYPE,
24154
- type,
24155
- key,
24156
- ref: void 0 !== config ? config : null,
24157
- props: maybeKey
24158
- };
24159
- }
24160
- exports.Fragment = REACT_FRAGMENT_TYPE;
24161
- exports.jsx = jsxProd;
24162
- exports.jsxs = jsxProd;
24163
- }));
24164
- //#endregion
24165
- //#region ../../node_modules/.pnpm/react@19.2.5/node_modules/react/cjs/react-jsx-runtime.development.js
24166
- /**
24167
- * @license React
24168
- * react-jsx-runtime.development.js
24169
- *
24170
- * Copyright (c) Meta Platforms, Inc. and affiliates.
24171
- *
24172
- * This source code is licensed under the MIT license found in the
24173
- * LICENSE file in the root directory of this source tree.
24174
- */
24175
- var require_react_jsx_runtime_development = /* @__PURE__ */ __commonJSMin(((exports) => {
24176
- "production" !== process.env.NODE_ENV && (function() {
24177
- function getComponentNameFromType(type) {
24178
- if (null == type) return null;
24179
- if ("function" === typeof type) return type.$$typeof === REACT_CLIENT_REFERENCE ? null : type.displayName || type.name || null;
24180
- if ("string" === typeof type) return type;
24181
- switch (type) {
24182
- case REACT_FRAGMENT_TYPE: return "Fragment";
24183
- case REACT_PROFILER_TYPE: return "Profiler";
24184
- case REACT_STRICT_MODE_TYPE: return "StrictMode";
24185
- case REACT_SUSPENSE_TYPE: return "Suspense";
24186
- case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList";
24187
- case REACT_ACTIVITY_TYPE: return "Activity";
24188
- }
24189
- if ("object" === typeof type) switch ("number" === typeof type.tag && console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."), type.$$typeof) {
24190
- case REACT_PORTAL_TYPE: return "Portal";
24191
- case REACT_CONTEXT_TYPE: return type.displayName || "Context";
24192
- case REACT_CONSUMER_TYPE: return (type._context.displayName || "Context") + ".Consumer";
24193
- case REACT_FORWARD_REF_TYPE:
24194
- var innerType = type.render;
24195
- type = type.displayName;
24196
- type || (type = innerType.displayName || innerType.name || "", type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef");
24197
- return type;
24198
- case REACT_MEMO_TYPE: return innerType = type.displayName || null, null !== innerType ? innerType : getComponentNameFromType(type.type) || "Memo";
24199
- case REACT_LAZY_TYPE:
24200
- innerType = type._payload;
24201
- type = type._init;
24202
- try {
24203
- return getComponentNameFromType(type(innerType));
24204
- } catch (x) {}
24205
- }
24206
- return null;
24207
- }
24208
- function testStringCoercion(value) {
24209
- return "" + value;
24210
- }
24211
- function checkKeyStringCoercion(value) {
24212
- try {
24213
- testStringCoercion(value);
24214
- var JSCompiler_inline_result = !1;
24215
- } catch (e) {
24216
- JSCompiler_inline_result = !0;
24217
- }
24218
- if (JSCompiler_inline_result) {
24219
- JSCompiler_inline_result = console;
24220
- var JSCompiler_temp_const = JSCompiler_inline_result.error;
24221
- var JSCompiler_inline_result$jscomp$0 = "function" === typeof Symbol && Symbol.toStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object";
24222
- JSCompiler_temp_const.call(JSCompiler_inline_result, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", JSCompiler_inline_result$jscomp$0);
24223
- return testStringCoercion(value);
24224
- }
24225
- }
24226
- function getTaskName(type) {
24227
- if (type === REACT_FRAGMENT_TYPE) return "<>";
24228
- if ("object" === typeof type && null !== type && type.$$typeof === REACT_LAZY_TYPE) return "<...>";
24229
- try {
24230
- var name = getComponentNameFromType(type);
24231
- return name ? "<" + name + ">" : "<...>";
24232
- } catch (x) {
24233
- return "<...>";
24234
- }
24235
- }
24236
- function getOwner() {
24237
- var dispatcher = ReactSharedInternals.A;
24238
- return null === dispatcher ? null : dispatcher.getOwner();
24239
- }
24240
- function UnknownOwner() {
24241
- return Error("react-stack-top-frame");
24242
- }
24243
- function hasValidKey(config) {
24244
- if (hasOwnProperty.call(config, "key")) {
24245
- var getter = Object.getOwnPropertyDescriptor(config, "key").get;
24246
- if (getter && getter.isReactWarning) return !1;
24247
- }
24248
- return void 0 !== config.key;
24249
- }
24250
- function defineKeyPropWarningGetter(props, displayName) {
24251
- function warnAboutAccessingKey() {
24252
- specialPropKeyWarningShown || (specialPropKeyWarningShown = !0, console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", displayName));
24253
- }
24254
- warnAboutAccessingKey.isReactWarning = !0;
24255
- Object.defineProperty(props, "key", {
24256
- get: warnAboutAccessingKey,
24257
- configurable: !0
24258
- });
24259
- }
24260
- function elementRefGetterWithDeprecationWarning() {
24261
- var componentName = getComponentNameFromType(this.type);
24262
- didWarnAboutElementRef[componentName] || (didWarnAboutElementRef[componentName] = !0, console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."));
24263
- componentName = this.props.ref;
24264
- return void 0 !== componentName ? componentName : null;
24265
- }
24266
- function ReactElement(type, key, props, owner, debugStack, debugTask) {
24267
- var refProp = props.ref;
24268
- type = {
24269
- $$typeof: REACT_ELEMENT_TYPE,
24270
- type,
24271
- key,
24272
- props,
24273
- _owner: owner
24274
- };
24275
- null !== (void 0 !== refProp ? refProp : null) ? Object.defineProperty(type, "ref", {
24276
- enumerable: !1,
24277
- get: elementRefGetterWithDeprecationWarning
24278
- }) : Object.defineProperty(type, "ref", {
24279
- enumerable: !1,
24280
- value: null
24281
- });
24282
- type._store = {};
24283
- Object.defineProperty(type._store, "validated", {
24284
- configurable: !1,
24285
- enumerable: !1,
24286
- writable: !0,
24287
- value: 0
24288
- });
24289
- Object.defineProperty(type, "_debugInfo", {
24290
- configurable: !1,
24291
- enumerable: !1,
24292
- writable: !0,
24293
- value: null
24294
- });
24295
- Object.defineProperty(type, "_debugStack", {
24296
- configurable: !1,
24297
- enumerable: !1,
24298
- writable: !0,
24299
- value: debugStack
24300
- });
24301
- Object.defineProperty(type, "_debugTask", {
24302
- configurable: !1,
24303
- enumerable: !1,
24304
- writable: !0,
24305
- value: debugTask
24306
- });
24307
- Object.freeze && (Object.freeze(type.props), Object.freeze(type));
24308
- return type;
24309
- }
24310
- function jsxDEVImpl(type, config, maybeKey, isStaticChildren, debugStack, debugTask) {
24311
- var children = config.children;
24312
- if (void 0 !== children) if (isStaticChildren) if (isArrayImpl(children)) {
24313
- for (isStaticChildren = 0; isStaticChildren < children.length; isStaticChildren++) validateChildKeys(children[isStaticChildren]);
24314
- Object.freeze && Object.freeze(children);
24315
- } else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");
24316
- else validateChildKeys(children);
24317
- if (hasOwnProperty.call(config, "key")) {
24318
- children = getComponentNameFromType(type);
24319
- var keys = Object.keys(config).filter(function(k) {
24320
- return "key" !== k;
24321
- });
24322
- isStaticChildren = 0 < keys.length ? "{key: someKey, " + keys.join(": ..., ") + ": ...}" : "{key: someKey}";
24323
- didWarnAboutKeySpread[children + isStaticChildren] || (keys = 0 < keys.length ? "{" + keys.join(": ..., ") + ": ...}" : "{}", console.error("A props object containing a \"key\" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />", isStaticChildren, children, keys, children), didWarnAboutKeySpread[children + isStaticChildren] = !0);
24324
- }
24325
- children = null;
24326
- void 0 !== maybeKey && (checkKeyStringCoercion(maybeKey), children = "" + maybeKey);
24327
- hasValidKey(config) && (checkKeyStringCoercion(config.key), children = "" + config.key);
24328
- if ("key" in config) {
24329
- maybeKey = {};
24330
- for (var propName in config) "key" !== propName && (maybeKey[propName] = config[propName]);
24331
- } else maybeKey = config;
24332
- children && defineKeyPropWarningGetter(maybeKey, "function" === typeof type ? type.displayName || type.name || "Unknown" : type);
24333
- return ReactElement(type, children, maybeKey, getOwner(), debugStack, debugTask);
24334
- }
24335
- function validateChildKeys(node) {
24336
- isValidElement(node) ? node._store && (node._store.validated = 1) : "object" === typeof node && null !== node && node.$$typeof === REACT_LAZY_TYPE && ("fulfilled" === node._payload.status ? isValidElement(node._payload.value) && node._payload.value._store && (node._payload.value._store.validated = 1) : node._store && (node._store.validated = 1));
24337
- }
24338
- function isValidElement(object) {
24339
- return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
24340
- }
24341
- var React = require_react(), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
24342
- return null;
24343
- };
24344
- React = { react_stack_bottom_frame: function(callStackForError) {
24345
- return callStackForError();
24346
- } };
24347
- var specialPropKeyWarningShown;
24348
- var didWarnAboutElementRef = {};
24349
- var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(React, UnknownOwner)();
24350
- var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
24351
- var didWarnAboutKeySpread = {};
24352
- exports.Fragment = REACT_FRAGMENT_TYPE;
24353
- exports.jsx = function(type, config, maybeKey) {
24354
- var trackActualOwner = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
24355
- return jsxDEVImpl(type, config, maybeKey, !1, trackActualOwner ? Error("react-stack-top-frame") : unknownOwnerDebugStack, trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask);
24356
- };
24357
- exports.jsxs = function(type, config, maybeKey) {
24358
- var trackActualOwner = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
24359
- return jsxDEVImpl(type, config, maybeKey, !0, trackActualOwner ? Error("react-stack-top-frame") : unknownOwnerDebugStack, trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask);
24360
- };
24361
- })();
24362
- }));
24363
- //#endregion
24364
- //#region src/cli/ink/components/project-select.tsx
24365
- var import_jsx_runtime = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
24366
- if (process.env.NODE_ENV === "production") module.exports = require_react_jsx_runtime_production();
24367
- else module.exports = require_react_jsx_runtime_development();
24368
- })))();
24369
- const MatchedName = ({ name, matchedIndices, isSelected }) => {
24370
- if (matchedIndices.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24371
- bold: isSelected,
24372
- wrap: "truncate-end",
24373
- children: name
24374
- });
24375
- const matchedIndexSet = new Set(matchedIndices);
24376
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24377
- bold: isSelected,
24378
- wrap: "truncate-end",
24379
- children: [...name].map((character, index) => matchedIndexSet.has(index) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24380
- color: "yellow",
24381
- children: character
24382
- }, index) : character)
24383
- });
24384
- };
24385
- const ProjectSelect = ({ packages, rootDirectory, onSubmit }) => {
24386
- const { rows: terminalRows } = useStdoutDimensions();
24387
- useExitOnCtrlC();
24388
- const [selectionMode, setSelectionMode] = (0, import_react.useState)("list");
24389
- const [searchQuery, setSearchQuery] = (0, import_react.useState)("");
24390
- const [selectedIndex, setSelectedIndex] = (0, import_react.useState)(0);
24391
- const [scrollOffset, setScrollOffset] = (0, import_react.useState)(0);
24392
- const [checkedDirectories, setCheckedDirectories] = (0, import_react.useState)(() => /* @__PURE__ */ new Set());
24393
- const didRecordProjectPathContext = (0, import_react.useRef)(false);
24394
- const matchedPackages = (0, import_react.useMemo)(() => {
24395
- const scoredPackages = packages.flatMap((workspacePackage) => {
24396
- const result = fuzzyMatch(searchQuery, workspacePackage.name);
24397
- return result ? [{
24398
- workspacePackage,
24399
- result
24400
- }] : [];
24401
- });
24402
- if (searchQuery.length > 0) scoredPackages.sort((leftPackage, rightPackage) => rightPackage.result.score - leftPackage.result.score);
24403
- return scoredPackages.map(({ workspacePackage, result }) => ({
24404
- workspacePackage,
24405
- matchedIndices: result.matchedIndices,
24406
- relativeDirectory: path.relative(rootDirectory, workspacePackage.directory) || "."
24407
- }));
24408
- }, [
24409
- packages,
24410
- rootDirectory,
24411
- searchQuery
24412
- ]);
24413
- const hasProjectPathContext = matchedPackages.some(({ relativeDirectory, workspacePackage }) => relativeDirectory !== workspacePackage.name);
24414
- (0, import_react.useEffect)(() => {
24415
- if (!hasProjectPathContext || didRecordProjectPathContext.current) return;
24416
- didRecordProjectPathContext.current = true;
24417
- recordCount(METRIC.tuiProjectPathContextShown);
24418
- }, [hasProjectPathContext]);
24419
- const isSearching = selectionMode === "search";
24420
- const hasFilterLine = isSearching || searchQuery.length > 0;
24421
- const listHeight = Math.max(1, Math.min(Math.max(matchedPackages.length, 1), terminalRows - 3 - (hasFilterLine ? 1 : 0)));
24422
- const selectedPackageIndex = matchedPackages.length === 0 ? 0 : clampNumber(selectedIndex, 0, matchedPackages.length - 1);
24423
- const selectedWorkspacePackage = matchedPackages[selectedPackageIndex]?.workspacePackage;
24424
- const updateFilter = (nextSearchQuery) => {
24425
- setSearchQuery(nextSearchQuery);
24426
- setSelectedIndex(0);
24427
- setScrollOffset(0);
24428
- };
24429
- const moveSelection = (indexDelta) => {
24430
- if (matchedPackages.length === 0) return;
24431
- const nextSelectedIndex = clampNumber(selectedPackageIndex + indexDelta, 0, matchedPackages.length - 1);
24432
- setSelectedIndex(nextSelectedIndex);
24433
- setScrollOffset((currentOffset) => {
24434
- if (nextSelectedIndex < currentOffset) return nextSelectedIndex;
24435
- if (nextSelectedIndex >= currentOffset + listHeight) return nextSelectedIndex - listHeight + 1;
24436
- return currentOffset;
24437
- });
24438
- };
24439
- const toggleCheckedDirectory = (directory) => {
24440
- setCheckedDirectories((currentCheckedDirectories) => {
24441
- const updatedCheckedDirectories = new Set(currentCheckedDirectories);
24442
- if (updatedCheckedDirectories.has(directory)) updatedCheckedDirectories.delete(directory);
24443
- else updatedCheckedDirectories.add(directory);
24444
- return updatedCheckedDirectories;
24445
- });
24446
- };
24447
- const submitDirectories = (directories) => {
24448
- onSubmit([...directories]);
24449
- };
24450
- const submitSelection = () => {
24451
- if (checkedDirectories.size > 0) {
24452
- const selectedDirectories = [];
24453
- for (const workspacePackage of packages) if (checkedDirectories.has(workspacePackage.directory)) selectedDirectories.push(workspacePackage.directory);
24454
- return submitDirectories(selectedDirectories);
24455
- }
24456
- if (selectedWorkspacePackage) submitDirectories([selectedWorkspacePackage.directory]);
24457
- };
24458
- useInput((input, key) => {
24459
- if (isSearching) {
24460
- if (key.return) return setSelectionMode("list");
24461
- if (key.escape) {
24462
- updateFilter("");
24463
- return setSelectionMode("list");
24464
- }
24465
- if (key.downArrow || key.ctrl && input === "n") return moveSelection(1);
24466
- if (key.upArrow || key.ctrl && input === "p") return moveSelection(-1);
24467
- if (key.backspace || key.delete) return updateFilter(searchQuery.slice(0, -1));
24468
- if (isPrintableInput(input) && !key.ctrl && !key.meta) updateFilter(searchQuery + input);
24469
- return;
24470
- }
24471
- if (input === "/") return setSelectionMode("search");
24472
- if (input === " ") {
24473
- if (selectedWorkspacePackage) toggleCheckedDirectory(selectedWorkspacePackage.directory);
24474
- return;
24475
- }
24476
- if (input === "a") {
24477
- if (matchedPackages.length === 0) return;
24478
- setCheckedDirectories((currentCheckedDirectories) => {
24479
- const updatedCheckedDirectories = new Set(currentCheckedDirectories);
24480
- const shouldClearMatches = matchedPackages.every((matchedPackage) => currentCheckedDirectories.has(matchedPackage.workspacePackage.directory));
24481
- for (const matchedPackage of matchedPackages) if (shouldClearMatches) updatedCheckedDirectories.delete(matchedPackage.workspacePackage.directory);
24482
- else updatedCheckedDirectories.add(matchedPackage.workspacePackage.directory);
24483
- return updatedCheckedDirectories;
24484
- });
24485
- return;
24486
- }
24487
- if (input === "q") return submitDirectories([]);
24488
- if (key.escape) {
24489
- if (searchQuery.length > 0) return updateFilter("");
24490
- if (checkedDirectories.size > 0) return setCheckedDirectories(/* @__PURE__ */ new Set());
24491
- return submitDirectories([]);
24492
- }
24493
- if (key.return) return submitSelection();
24494
- if (key.downArrow || input === "j") return moveSelection(1);
24495
- if (key.upArrow || input === "k") return moveSelection(-1);
24496
- if (key.pageDown) return moveSelection(listHeight);
24497
- if (key.pageUp) return moveSelection(-listHeight);
24498
- });
24499
- const visibleStart = resolveVisibleStart({
24500
- itemCount: matchedPackages.length,
24501
- offset: scrollOffset,
24502
- selectedIndex: selectedPackageIndex,
24503
- viewportHeight: listHeight
24504
- });
24505
- const visibleMatches = matchedPackages.slice(visibleStart, visibleStart + listHeight);
24506
- const longestNameLength = Math.max(0, ...packages.map((workspacePackage) => workspacePackage.name.length));
24507
- let filterLine = null;
24508
- if (isSearching) filterLine = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
24509
- wrap: "truncate-end",
24510
- children: [
24511
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24512
- color: "cyan",
24513
- children: "/ "
24514
- }),
24515
- searchQuery.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: searchQuery }) : null,
24516
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24517
- inverse: true,
24518
- children: " "
24519
- })
24520
- ]
24521
- });
24522
- else if (searchQuery.length > 0) filterLine = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24523
- dimColor: true,
24524
- wrap: "truncate-end",
24525
- children: `filter: ${searchQuery}`
24526
- });
24527
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
24528
- flexDirection: "column",
24529
- children: [
24530
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
24531
- wrap: "truncate-end",
24532
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24533
- bold: true,
24534
- children: "Select projects to scan"
24535
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
24536
- dimColor: true,
24537
- children: [
24538
- " ",
24539
- checkedDirectories.size,
24540
- "/",
24541
- packages.length
24542
- ]
24543
- })]
24544
- }),
24545
- filterLine,
24546
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
24547
- flexDirection: "column",
24548
- height: listHeight,
24549
- children: matchedPackages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24550
- dimColor: true,
24551
- children: "No matching projects"
24552
- }) : visibleMatches.map((matchedPackage, visiblePackageIndex) => {
24553
- const isSelected = visibleStart + visiblePackageIndex === selectedPackageIndex;
24554
- const isChecked = checkedDirectories.has(matchedPackage.workspacePackage.directory);
24555
- const shouldShowRelativeDirectory = matchedPackage.relativeDirectory !== matchedPackage.workspacePackage.name;
24556
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
24557
- wrap: "truncate-end",
24558
- children: [
24559
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24560
- color: isSelected ? "cyan" : void 0,
24561
- children: isSelected ? `${figures.pointer} ` : " "
24562
- }),
24563
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24564
- color: isChecked ? "green" : void 0,
24565
- children: isChecked ? `${figures.radioOn} ` : `${figures.radioOff} `
24566
- }),
24567
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MatchedName, {
24568
- name: matchedPackage.workspacePackage.name,
24569
- matchedIndices: matchedPackage.matchedIndices,
24570
- isSelected
24571
- }),
24572
- shouldShowRelativeDirectory ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
24573
- dimColor: true,
24574
- children: [" ".repeat(longestNameLength - matchedPackage.workspacePackage.name.length + 2), matchedPackage.relativeDirectory]
24575
- }) : null
24576
- ]
24577
- }, matchedPackage.workspacePackage.directory);
24578
- })
24579
- }),
24580
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
24581
- marginTop: 1,
24582
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24583
- dimColor: true,
24584
- wrap: "truncate-end",
24585
- children: isSearching ? "type to filter · enter confirm · esc clear" : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
24586
- "space select · a all · / search · ",
24587
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24588
- color: "cyan",
24589
- children: "enter"
24590
- }),
24591
- " to submit · q cancel"
24592
- ] })
24593
- })
24594
- })
24595
- ]
24596
- });
24597
- };
24598
- //#endregion
24599
- //#region src/cli/utils/onboarding-pacing.ts
24600
- const FORCE_ONBOARDING_ENV_VAR = "REACT_DOCTOR_FORCE_ONBOARDING";
24601
- const FALSY_FLAG_VALUES = new Set([
24602
- "",
24603
- "0",
24604
- "false"
24605
- ]);
24606
- const isOnboardingForced = (environment = process.env) => {
24607
- const value = environment[FORCE_ONBOARDING_ENV_VAR];
24608
- return value !== void 0 && !FALSY_FLAG_VALUES.has(value.toLowerCase());
24609
- };
24610
- const shouldRecordOnboarding = (input) => input.paceOnboardingSections && !input.forceOnboarding && !input.verbose && !input.isNonInteractiveEnvironment;
24611
- const canAnimateOnboarding = (stream = process.stdout) => {
24612
- if (!(stream.isTTY === true && (stream.columns ?? 0) > 0 && process.env.TERM !== "dumb")) return false;
24613
- if (isOnboardingForced()) return true;
24614
- return !isGitHookEnvironment() && !isCiEnvironment();
24615
- };
24616
- //#endregion
24617
- //#region src/cli/utils/onboarding-state.ts
24618
- const ONBOARDING_GATE = {
24619
- id: ONBOARDING_EVENT,
24620
- scope: "global"
24621
- };
24622
- const markOnboardingComplete = (options = {}) => {
24623
- if (isGatePending(ONBOARDING_GATE, {}, options)) recordGate(ONBOARDING_GATE, {}, options);
24624
- };
24625
- //#endregion
24626
- //#region src/cli/ink/hooks/use-report-reveal.ts
24627
- const useReportReveal = ({ issueCount, onRevealComplete }) => {
24628
- const { stdout } = useStdout();
24629
- const shouldAnimate = issueCount > 0 && canAnimateOnboarding(stdout ?? void 0);
24630
- const streamStepCount = Math.min(12, Math.max(issueCount, 8));
24631
- const [streamStep, setStreamStep] = (0, import_react.useState)(0);
24632
- const [didRevealActions, setDidRevealActions] = (0, import_react.useState)(false);
24633
- const didNotifyRevealComplete = (0, import_react.useRef)(false);
24634
- const isStreaming = shouldAnimate && streamStep < streamStepCount;
24635
- const didReachActions = shouldAnimate ? didRevealActions : stdout?.isTTY === true;
24636
- (0, import_react.useEffect)(() => {
24637
- if (!shouldAnimate) return;
24638
- let nextStreamStep = 0;
24639
- const intervalId = setInterval(() => {
24640
- nextStreamStep = Math.min(streamStepCount, nextStreamStep + 1);
24641
- setStreamStep(nextStreamStep);
24642
- if (nextStreamStep === streamStepCount) clearInterval(intervalId);
24643
- }, 125);
24644
- return () => clearInterval(intervalId);
24645
- }, [shouldAnimate, streamStepCount]);
24646
- (0, import_react.useEffect)(() => {
24647
- if (!shouldAnimate || isStreaming) return;
24648
- const timeoutId = setTimeout(() => setDidRevealActions(true), 850);
24649
- return () => clearTimeout(timeoutId);
24650
- }, [isStreaming, shouldAnimate]);
24651
- (0, import_react.useEffect)(() => {
24652
- if (!didReachActions || didNotifyRevealComplete.current) return;
24653
- didNotifyRevealComplete.current = true;
24654
- onRevealComplete?.();
24655
- }, [didReachActions, onRevealComplete]);
24656
- if (!shouldAnimate) return {
24657
- phase: "actions",
24658
- streamSelectedIndex: 0
24659
- };
24660
- if (isStreaming) return {
24661
- phase: "streaming",
24662
- streamSelectedIndex: streamStep % issueCount
24663
- };
24664
- return {
24665
- phase: didRevealActions ? "actions" : "score",
24666
- streamSelectedIndex: 0
24667
- };
24668
- };
24669
- //#endregion
24670
- //#region src/cli/ink/lib/diagnostic-list-entries.ts
24671
- const CATEGORY_RANK = new Map(DIAGNOSTIC_CATEGORY_BUCKETS.map((category, index) => [category, index]));
24672
- const buildDiagnosticListEntries = (rows) => {
24673
- const rowsByCategory = /* @__PURE__ */ new Map();
24674
- for (const [rowIndex, row] of rows.entries()) {
24675
- const categoryRows = rowsByCategory.get(row.category) ?? [];
24676
- categoryRows.push({
24677
- row,
24678
- rowIndex
24679
- });
24680
- rowsByCategory.set(row.category, categoryRows);
24681
- }
24682
- const orderedCategories = [...rowsByCategory.keys()].sort((categoryA, categoryB) => {
24683
- const rankDelta = (CATEGORY_RANK.get(categoryA) ?? Number.MAX_SAFE_INTEGER) - (CATEGORY_RANK.get(categoryB) ?? Number.MAX_SAFE_INTEGER);
24684
- return rankDelta !== 0 ? rankDelta : categoryA.localeCompare(categoryB);
24685
- });
24686
- const entries = [];
24687
- for (const category of orderedCategories) {
24688
- const categoryRows = rowsByCategory.get(category) ?? [];
24689
- entries.push({
24690
- kind: "header",
24691
- category
24692
- });
24693
- for (const indexedRow of categoryRows) entries.push({
24694
- kind: "item",
24695
- ...indexedRow
24696
- });
24697
- }
24698
- return entries;
24699
- };
24700
- //#endregion
24701
- //#region src/cli/ink/lib/diagnostic-rows.ts
24702
- const buildDiagnosticRows = (diagnostics, scores) => {
24703
- return buildSortedRuleGroups(diagnostics, buildRulePriorityMap(scores)).map(([ruleKey, ruleDiagnostics]) => {
24704
- const representative = ruleDiagnostics.find((diagnostic) => diagnostic.line > 0) ?? ruleDiagnostics[0];
24705
- return {
24706
- ruleKey,
24707
- diagnostics: ruleDiagnostics,
24708
- severity: representative.severity === "error" ? "error" : "warning",
24709
- category: representative.category,
24710
- title: representative.title ?? ruleKey,
24711
- location: formatDiagnosticSite(representative),
24712
- siteCount: ruleDiagnostics.length,
24713
- representative,
24714
- ruleGuideUrl: hasPublishedFixRecipe(representative) ? buildRuleDocsUrl(representative.plugin, representative.rule) : null
24715
- };
24716
- });
24717
- };
24718
- //#endregion
24719
- //#region src/cli/ink/lib/resolve-report-layout.ts
24720
- const STACKED_FIXED_ROWS = 9;
24721
- const resolveReportLayout = ({ columns, diagnosticEntryCount, terminalRows }) => {
24722
- const width = Math.max(1, columns - 2);
24723
- const reportRows = Math.max(0, terminalRows - 1);
24724
- const isWide = columns >= 120 && terminalRows >= 22;
24725
- const isCompact = !isWide && terminalRows <= TUI_REPORT_COMPACT_MAX_ROWS;
24726
- const showsViewerScoreHeader = !isCompact || reportRows >= 8;
24727
- const detailHeight = Math.max(0, isWide ? reportRows - 3 : Math.min(15, reportRows - STACKED_FIXED_ROWS - 3));
24728
- const availableListHeight = isWide ? Math.max(3, detailHeight - 4 - 1) : Math.max(3, reportRows - STACKED_FIXED_ROWS - detailHeight);
24729
- const isStackedReportCapped = !isCompact && !isWide && availableListHeight > 16;
24730
- let listHeight = availableListHeight;
24731
- if (isCompact) {
24732
- const viewerScoreHeaderRows = showsViewerScoreHeader ? 4 : 0;
24733
- listHeight = Math.min(diagnosticEntryCount, Math.max(3, reportRows - 1 - viewerScoreHeaderRows));
24734
- } else if (!isWide) listHeight = Math.min(diagnosticEntryCount, 16, availableListHeight);
24735
- const detailColumnWidth = Math.max(20, Math.floor(width * TUI_REPORT_DETAIL_WIDTH_FRACTION));
24736
- const listColumnWidth = Math.max(20, width - detailColumnWidth - 3);
24737
- let layout = "stacked";
24738
- if (isCompact) layout = "compact";
24739
- else if (isWide) layout = "split";
24740
- return {
24741
- detailColumnWidth,
24742
- detailHeight,
24743
- isStackedReportCapped,
24744
- layout,
24745
- listColumnWidth,
24746
- listHeight,
24747
- showsViewerScoreHeader,
24748
- width
24749
- };
24750
- };
24751
- //#endregion
24752
- //#region src/cli/ink/components/action-menu.tsx
24753
- const ActionMenu = ({ actions, selectedIndex: controlledSelectedIndex, onSelectionChange, onEscape, onQuit }) => {
24754
- const [internalSelectedIndex, setInternalSelectedIndex] = (0, import_react.useState)(0);
24755
- const selectedIndex = controlledSelectedIndex ?? internalSelectedIndex;
24756
- const changeSelection = onSelectionChange ?? setInternalSelectedIndex;
24757
- useInput((input, key) => {
24758
- if (input === "q") return onQuit();
24759
- if (key.escape) return onEscape();
24760
- if (actions.length === 0) return;
24761
- if (key.upArrow || input === "k") return changeSelection(Math.max(0, selectedIndex - 1));
24762
- if (key.downArrow || input === "j") return changeSelection(Math.min(actions.length - 1, selectedIndex + 1));
24763
- if (key.return) actions[selectedIndex]?.onSelect();
24764
- });
24765
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
24766
- flexDirection: "column",
24767
- marginTop: 1,
24768
- children: actions.map((action, index) => {
24769
- const isSelected = index === selectedIndex;
24770
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
24771
- flexDirection: "column",
24772
- marginBottom: index < actions.length - 1 ? 1 : void 0,
24773
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
24774
- color: isSelected ? "cyan" : void 0,
24775
- bold: isSelected,
24776
- children: [
24777
- isSelected ? figures.pointer : figures.pointerSmall,
24778
- " ",
24779
- action.label
24780
- ]
24781
- }), isSelected ? action.description : null]
24782
- }, action.id);
24783
- })
24784
- });
24785
- };
24786
- //#endregion
24787
- //#region src/cli/ink/components/agent-handoff.tsx
24788
- const AgentHandoff = ({ agents, onSelect, onBack, onQuit }) => {
24789
- const actions = agents.map((agentId) => ({
24790
- id: agentId,
24791
- label: getSkillAgentConfig(agentId).displayName,
24792
- onSelect: () => onSelect(agentId)
24793
- }));
24794
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
24795
- flexDirection: "column",
24796
- children: [
24797
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
24798
- paddingLeft: 2,
24799
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24800
- bold: true,
24801
- children: "Choose an agent"
24802
- })
24803
- }),
24804
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ActionMenu, {
24805
- actions,
24806
- onEscape: onBack,
24807
- onQuit
24808
- }),
24809
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
24810
- marginTop: 1,
24811
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24812
- dimColor: true,
24813
- children: "↑/↓ move · enter select · esc back · q quit"
24814
- })
24815
- })
24816
- ]
24817
- });
24818
- };
24819
- //#endregion
24820
- //#region src/cli/utils/format-hyperlink.ts
24821
- const OSC = "\x1B]";
24822
- const ST = "\x1B\\";
24823
- /**
24824
- * Wraps `text` in an OSC 8 hyperlink pointing at `uri`. The visible characters
24825
- * are exactly `text`; the link is carried in escape sequences a capable
24826
- * terminal turns into a click target.
24827
- */
24828
- const formatHyperlink = (text, uri) => `${OSC}8;;${uri}${ST}${text}${OSC}8;;${ST}`;
24829
- //#endregion
24830
- //#region src/cli/utils/supports-hyperlinks.ts
24831
- const HYPERLINK_CAPABLE_TERM_PROGRAMS = new Set([
24832
- "iTerm.app",
24833
- "WezTerm",
24834
- "vscode",
24835
- "Hyper",
24836
- "ghostty",
24837
- "Tabby",
24838
- "rio"
24839
- ]);
24840
- const parseVteVersion = (raw) => {
24841
- const parsed = Number.parseInt(raw ?? "", 10);
24842
- return Number.isNaN(parsed) ? 0 : parsed;
24843
- };
24844
- /**
24845
- * Whether `stream` is a terminal that renders OSC 8 hyperlinks. Auto-detected
24846
- * from terminal-identity env vars; the de-facto `FORCE_HYPERLINK` env var
24847
- * overrides detection (`FORCE_HYPERLINK=0`/`false` forces off, any other value
24848
- * forces on), mirroring how the ecosystem's terminal libraries gate the same
24849
- * feature. Off for non-TTYs, `TERM=dumb`, and CI (whose log viewers render the
24850
- * raw escape rather than a link). Unknown terminals default to off.
24851
- */
24852
- const supportsHyperlinks = (stream = process.stdout, env = process.env) => {
24853
- const forced = env.FORCE_HYPERLINK;
24854
- if (forced !== void 0 && forced !== "") return forced !== "0" && forced.toLowerCase() !== "false";
24855
- if (stream.isTTY !== true) return false;
24856
- if (env.TERM === "dumb") return false;
24857
- if (isCiEnvironment(env)) return false;
24858
- if (env.WT_SESSION) return true;
24859
- if (env.KITTY_WINDOW_ID || env.TERM === "xterm-kitty") return true;
24860
- if (parseVteVersion(env.VTE_VERSION) >= 5e3) return true;
24861
- return Boolean(env.TERM_PROGRAM && HYPERLINK_CAPABLE_TERM_PROGRAMS.has(env.TERM_PROGRAM));
24862
- };
24863
- //#endregion
24864
- //#region src/cli/ink/components/tui-link.tsx
24865
- const TuiLink = ({ children, url }) => {
24866
- const shouldFormatHyperlink = supportsHyperlinks();
24867
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Transform, {
24868
- transform: (text) => shouldFormatHyperlink ? formatHyperlink(text, url) : text,
24869
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children })
24870
- });
24871
- };
24872
- //#endregion
24873
- //#region src/cli/ink/components/ci-justification.tsx
24874
- const CiJustification = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
24875
- flexDirection: "column",
24876
- paddingLeft: 2,
24877
- children: [
24878
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24879
- dimColor: true,
24880
- children: "Scan every pull request to prevent new React issues while you fix the backlog."
24881
- }),
24882
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
24883
- dimColor: true,
24884
- children: [
24885
- "Used by teams at ",
24886
- CI_TRUST_COMPANIES,
24887
- "."
24888
- ]
24889
- }),
24890
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TuiLink, {
24891
- url: GITHUB_ACTIONS_SETUP_URL,
24892
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24893
- color: "cyan",
24894
- children: GITHUB_ACTIONS_SETUP_URL
24895
- })
24896
- })
24897
- ]
24898
- });
24899
- //#endregion
24900
- //#region src/cli/ink/components/ci-setup.tsx
24901
- const CiSetup = ({ feedback, onConfirm, onLearnMore, onBack, onQuit }) => {
24902
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
24903
- flexDirection: "column",
24904
- children: [
24905
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
24906
- bold: true,
24907
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24908
- color: "cyan",
24909
- children: "?"
24910
- }), " Add React Doctor to GitHub Actions?"]
24911
- }),
24912
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CiJustification, {}),
24913
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ActionMenu, {
24914
- actions: [{
24915
- id: "confirm",
24916
- label: "Yes, add the workflow",
24917
- onSelect: onConfirm
24918
- }, {
24919
- id: "learn-more",
24920
- label: "Open the GitHub Actions guide",
24921
- onSelect: onLearnMore
24922
- }],
24923
- onEscape: onBack,
24924
- onQuit
24925
- }),
24926
- feedback ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24927
- color: feedback.didSucceed ? "green" : "yellow",
24928
- children: feedback.didSucceed ? feedback.message : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TuiLink, {
24929
- url: GITHUB_ACTIONS_SETUP_URL,
24930
- children: feedback.message
24931
- })
24932
- }) : null,
24933
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
24934
- marginTop: 1,
24935
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
24936
- dimColor: true,
24937
- children: "↑/↓ move · enter select · esc back · q quit"
24938
- })
24939
- })
24940
- ]
24941
- });
24942
- };
24943
- //#endregion
24944
- //#region src/cli/ink/hooks/use-scroll-viewport.ts
24945
- const useScrollViewport = (options) => {
24946
- const { itemCount, height, initialSelectedIndex = 0, isActive = true, isSelectable, onSelectedIndexChange } = options;
24947
- const canSelect = (index) => index >= 0 && index < itemCount && (isSelectable ? isSelectable(index) : true);
24948
- const seekSelectable = (start, step) => {
24949
- for (let index = start; index >= 0 && index < itemCount; index += step) if (canSelect(index)) return index;
24950
- return -1;
24951
- };
24952
- const nearestSelectable = (target, step) => {
24953
- const ahead = seekSelectable(target, step);
24954
- if (ahead !== -1) return ahead;
24955
- const behind = seekSelectable(target, -step);
24956
- return behind === -1 ? target : behind;
24957
- };
24958
- const [selectedIndex, setSelectedIndex] = (0, import_react.useState)(() => {
24959
- const first = seekSelectable(clampNumber(initialSelectedIndex, 0, itemCount - 1), 1);
24960
- return first === -1 ? 0 : first;
24961
- });
24962
- const [offset, setOffset] = (0, import_react.useState)(0);
24963
- const awaitingSecondG = (0, import_react.useRef)(false);
24964
- const moveTo = (rawIndex, step) => {
24965
- const nextSelectedIndex = nearestSelectable(clampNumber(rawIndex, 0, itemCount - 1), step);
24966
- setSelectedIndex(nextSelectedIndex);
24967
- onSelectedIndexChange?.(nextSelectedIndex);
24968
- setOffset((currentOffset) => {
24969
- if (nextSelectedIndex < currentOffset) return nextSelectedIndex;
24970
- if (nextSelectedIndex >= currentOffset + height) return nextSelectedIndex - height + 1;
24971
- return currentOffset;
24972
- });
24973
- };
24974
- useInput((input, key) => {
24975
- if (itemCount === 0) return;
24976
- const isSecondG = awaitingSecondG.current && input === "g";
24977
- if (input !== "g") awaitingSecondG.current = false;
24978
- if (key.downArrow || input === "j") return moveTo(selectedIndex + 1, 1);
24979
- if (key.upArrow || input === "k") return moveTo(selectedIndex - 1, -1);
24980
- if (key.pageDown) return moveTo(selectedIndex + height, 1);
24981
- if (key.pageUp) return moveTo(selectedIndex - height, -1);
24982
- if (key.ctrl && input === "d") return moveTo(selectedIndex + Math.floor(height / 2), 1);
24983
- if (key.ctrl && input === "u") return moveTo(selectedIndex - Math.floor(height / 2), -1);
24984
- if (input === "G") return moveTo(itemCount - 1, -1);
24985
- if (isSecondG) {
24986
- awaitingSecondG.current = false;
24987
- return moveTo(0, 1);
24988
- }
24989
- if (input === "g") awaitingSecondG.current = true;
24990
- }, { isActive });
24991
- const resolvedSelected = canSelect(selectedIndex) ? selectedIndex : nearestSelectable(clampNumber(selectedIndex, 0, itemCount - 1), 1);
24992
- const visibleStart = resolveVisibleStart({
24993
- itemCount,
24994
- offset,
24995
- selectedIndex: resolvedSelected,
24996
- viewportHeight: height
24997
- });
24998
- return {
24999
- selectedIndex: resolvedSelected,
25000
- visibleStart,
25001
- visibleEnd: Math.min(itemCount, visibleStart + height)
25002
- };
25003
- };
25004
- //#endregion
25005
- //#region src/cli/ink/lib/build-issue-prompt.ts
25006
- const buildIssuePrompt = ({ row, projectName }) => {
25007
- const { representative } = row;
25008
- const severityLabel = row.severity === "error" ? "ERROR" : "WARN";
25009
- const uniqueSites = [...new Set(row.diagnostics.map(formatDiagnosticSite))];
25010
- const inlineSites = uniqueSites.slice(0, 8);
25011
- const remainingSiteCount = uniqueSites.length - inlineSites.length;
25012
- const lines = [
25013
- `Fix exactly one React Doctor rule in ${projectName}:`,
25014
- "",
25015
- `${severityLabel} ${row.category}: ${row.title} (${row.ruleKey}, ×${row.siteCount})`,
25016
- representative.message
25017
- ];
25018
- if (representative.help) lines.push("", `Suggested fix: ${representative.help}`);
25019
- const fixRecipeLine = formatFixRecipeLine(representative);
25020
- if (fixRecipeLine) lines.push("", fixRecipeLine);
25021
- lines.push("", "Scope:", `- Fix only ${row.ruleKey}.`, "- Fix the root cause; do not suppress, disable, or silence the rule.", "- Keep unrelated refactors out of this pass.", "", "Affected sites:", ...inlineSites.map((site) => `- ${site}`));
25022
- if (remainingSiteCount > 0) lines.push(`- +${remainingSiteCount} more sites`);
25023
- const learnMoreLine = formatLearnMoreLine(representative);
25024
- if (learnMoreLine) lines.push("", learnMoreLine);
25025
- lines.push("", `Verify with \`npx react-doctor@latest --verbose\` and confirm ${row.ruleKey} is gone before moving on.`);
25026
- return lines.join("\n");
25027
- };
25028
- //#endregion
25029
- //#region src/cli/ink/lib/severity-variants.ts
25030
- const ICONS = isUnicodeSupported() ? {
25031
- error: "✖",
25032
- warning: "⚠"
25033
- } : {
25034
- error: "x",
25035
- warning: "!"
25036
- };
25037
- const severityVariant = (severity) => severity === "error" ? {
25038
- color: "red",
25039
- icon: ICONS.error,
25040
- label: "error"
25041
- } : {
25042
- color: "yellow",
25043
- icon: ICONS.warning,
25044
- label: "warning"
25045
- };
25046
- //#endregion
25047
- //#region src/cli/ink/components/diagnostic-detail.tsx
25048
- const DiagnosticDetail = ({ row, rootDirectory }) => {
25049
- const codeFrame = (0, import_react.useMemo)(() => {
25050
- if (!row) return null;
25051
- const { representative } = row;
25052
- return buildCodeFrame({
25053
- filePath: representative.filePath,
25054
- line: representative.line,
25055
- column: representative.column,
25056
- rootDirectory
25057
- });
25058
- }, [row, rootDirectory]);
25059
- if (!row) return null;
25060
- const variant = severityVariant(row.severity);
25061
- const { representative } = row;
25062
- const impact = getCategoryImpact(row.category);
25063
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25064
- flexDirection: "column",
25065
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25066
- wrap: "truncate-end",
25067
- children: [
25068
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25069
- color: variant.color,
25070
- children: [variant.icon, " "]
25071
- }),
25072
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25073
- color: variant.color,
25074
- bold: true,
25075
- children: row.title
25076
- }),
25077
- row.siteCount > 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25078
- dimColor: true,
25079
- children: [" ×", row.siteCount]
25080
- }) : null
25081
- ]
25082
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25083
- flexDirection: "column",
25084
- paddingLeft: 2,
25085
- children: [
25086
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25087
- dimColor: true,
25088
- wrap: "truncate-end",
25089
- children: [
25090
- row.category,
25091
- " · ",
25092
- variant.label,
25093
- " · ",
25094
- row.location,
25095
- representative.fileContext ? ` · ${representative.fileContext} file` : ""
25096
- ]
25097
- }),
25098
- impact ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25099
- marginTop: 1,
25100
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25101
- wrap: "wrap",
25102
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25103
- color: "cyan",
25104
- children: "Impact "
25105
- }), impact]
25106
- })
25107
- }) : null,
25108
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25109
- marginTop: 1,
25110
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25111
- wrap: "wrap",
25112
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25113
- color: "cyan",
25114
- children: "Why "
25115
- }), representative.message]
25116
- })
25117
- }),
25118
- codeFrame ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25119
- marginTop: 1,
25120
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: codeFrame })
25121
- }) : null,
25122
- representative.help ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25123
- marginTop: 1,
25124
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25125
- wrap: "wrap",
25126
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25127
- color: "cyan",
25128
- children: "Fix "
25129
- }), representative.help]
25130
- })
25131
- }) : null,
25132
- row.ruleGuideUrl ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25133
- marginTop: 1,
25134
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25135
- color: "blue",
25136
- wrap: "truncate-end",
25137
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TuiLink, {
25138
- url: row.ruleGuideUrl,
25139
- children: ["Rule guide: ", row.ruleGuideUrl]
25140
- })
25141
- })
25142
- }) : null
25143
- ]
25144
- })]
25145
- });
25146
- };
25147
- //#endregion
25148
- //#region src/cli/ink/components/diagnostic-item.tsx
25149
- const DiagnosticItem = ({ row, isSelected, isRead }) => {
25150
- const variant = severityVariant(row.severity);
25151
- const shouldHighlightSeverity = isSelected || !isRead;
25152
- let marker = "• ";
25153
- if (isRead) marker = " ";
25154
- if (isSelected) marker = "› ";
25155
- let markerColor = shouldHighlightSeverity ? variant.color : void 0;
25156
- if (isSelected) markerColor = "cyan";
25157
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25158
- wrap: "truncate-end",
25159
- dimColor: isRead && !isSelected,
25160
- children: [
25161
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25162
- color: markerColor,
25163
- children: marker
25164
- }),
25165
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25166
- color: shouldHighlightSeverity ? variant.color : void 0,
25167
- children: `${variant.icon} `
25168
- }),
25169
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25170
- color: shouldHighlightSeverity ? variant.color : void 0,
25171
- bold: isSelected,
25172
- children: row.title
25173
- }),
25174
- row.siteCount > 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25175
- dimColor: true,
25176
- children: [" ×", row.siteCount]
25177
- }) : null
25178
- ]
25179
- });
25180
- };
25181
- //#endregion
25182
- //#region src/cli/ink/components/status-bar.tsx
25183
- const StatusBar = ({ total, errorCount, warningCount, position, issueCount, unreadCount, projectCount, keyHints = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25184
- dimColor: true,
25185
- children: "↑/↓ to move"
25186
- }), exitHint = "q to quit", compact = false }) => {
25187
- const counts = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
25188
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25189
- bold: true,
25190
- children: pluralize(total, "finding")
25191
- }),
25192
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25193
- dimColor: true,
25194
- children: " "
25195
- }),
25196
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25197
- color: "red",
25198
- children: pluralize(errorCount, "error")
25199
- }),
25200
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25201
- dimColor: true,
25202
- children: " "
25203
- }),
25204
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25205
- color: "yellow",
25206
- children: pluralize(warningCount, "warning")
25207
- })
25208
- ] });
25209
- if (compact) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25210
- wrap: "truncate-end",
25211
- children: [
25212
- counts,
25213
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25214
- dimColor: true,
25215
- children: [
25216
- " · ",
25217
- "issue ",
25218
- position,
25219
- "/",
25220
- issueCount,
25221
- " · "
25222
- ]
25223
- }),
25224
- keyHints,
25225
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25226
- dimColor: true,
25227
- children: [" · ", exitHint]
25228
- })
25229
- ]
25230
- });
25231
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25232
- flexDirection: "column",
25233
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25234
- wrap: "truncate-end",
25235
- children: [
25236
- counts,
25237
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25238
- dimColor: true,
25239
- children: [
25240
- " · ",
25241
- "issue ",
25242
- position,
25243
- "/",
25244
- issueCount
25245
- ]
25246
- }),
25247
- projectCount !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25248
- dimColor: true,
25249
- children: [" · ", pluralize(projectCount, "project")]
25250
- }) : null
25251
- ]
25252
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25253
- wrap: "truncate-end",
25254
- children: [
25255
- unreadCount !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25256
- color: unreadCount > 0 ? "cyan" : void 0,
25257
- dimColor: unreadCount === 0,
25258
- children: [
25259
- pluralize(unreadCount, "issue"),
25260
- " unread",
25261
- " · "
25262
- ]
25263
- }) : null,
25264
- keyHints,
25265
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25266
- dimColor: true,
25267
- children: [" · ", exitHint]
25268
- })
25269
- ]
25270
- })]
25271
- });
25272
- };
25273
- //#endregion
25274
- //#region src/cli/ink/components/diagnostic-list.tsx
25275
- const DIAGNOSTIC_KEY_HINTS = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
25276
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25277
- dimColor: true,
25278
- children: "↑/↓ move · "
25279
- }),
25280
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25281
- color: "cyan",
25282
- children: "enter"
25283
- }),
25284
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25285
- dimColor: true,
25286
- children: " copy context"
25287
- })
25288
- ] });
25289
- const DiagnosticList = ({ header, rows, entries, width, listColumnWidth, detailColumnWidth, listHeight, detailHeight, layout, rootDirectory, projectName, projectCount, initialSelectedRowIndex, readRuleKeys, onSelectedRowIndexChange, onQuit, onBack = onQuit, exitHint }) => {
25290
- const isSplit = layout === "split";
25291
- const isCompact = layout === "compact";
25292
- const initialSelectedEntryIndex = initialSelectedRowIndex === null ? 0 : Math.max(0, entries.findIndex((entry) => entry.kind === "item" && entry.rowIndex === initialSelectedRowIndex));
25293
- const { selectedIndex: selectedEntryIndex, visibleStart: visibleEntryStart, visibleEnd: visibleEntryEnd } = useScrollViewport({
25294
- itemCount: entries.length,
25295
- height: listHeight,
25296
- initialSelectedIndex: initialSelectedEntryIndex,
25297
- isSelectable: (entryIndex) => entries[entryIndex]?.kind === "item",
25298
- onSelectedIndexChange: (entryIndex) => {
25299
- const entry = entries[entryIndex];
25300
- if (entry?.kind === "item") onSelectedRowIndexChange(entry.rowIndex);
25301
- }
25302
- });
25303
- const visibleEntries = entries.slice(visibleEntryStart, visibleEntryEnd);
25304
- const selectedEntry = entries[selectedEntryIndex];
25305
- const selected = selectedEntry?.kind === "item" ? selectedEntry.row : null;
25306
- const selectedRuleKey = selected?.ruleKey ?? null;
25307
- const initialSelectedRuleKey = (0, import_react.useRef)(selectedRuleKey);
25308
- const didRecordFindingNavigation = (0, import_react.useRef)(false);
25309
- const [copiedRuleKey, setCopiedRuleKey] = (0, import_react.useState)(null);
25310
- const [copyFailedRuleKey, setCopyFailedRuleKey] = (0, import_react.useState)(null);
25311
- const effectiveReadRuleKeys = (0, import_react.useMemo)(() => {
25312
- if (!selectedRuleKey || readRuleKeys.has(selectedRuleKey)) return readRuleKeys;
25313
- return new Set(readRuleKeys).add(selectedRuleKey);
25314
- }, [readRuleKeys, selectedRuleKey]);
25315
- (0, import_react.useEffect)(() => {
25316
- if (!selectedRuleKey || selectedRuleKey === initialSelectedRuleKey.current || didRecordFindingNavigation.current) return;
25317
- didRecordFindingNavigation.current = true;
25318
- recordCount(METRIC.tuiFindingNavigated);
25319
- }, [selectedRuleKey]);
25320
- const copySelectedIssueContext = () => {
25321
- if (!selected) return;
25322
- const issuePrompt = buildIssuePrompt({
25323
- row: selected,
25324
- projectName
25325
- });
25326
- const ruleKey = selected.ruleKey;
25327
- copyToClipboard(issuePrompt).then((didCopyIssueContext) => {
25328
- if (didCopyIssueContext) {
25329
- setCopiedRuleKey(ruleKey);
25330
- setCopyFailedRuleKey(null);
25331
- return;
25332
- }
25333
- recordCount(METRIC.tuiReportActionSelected, 1, { action: "copy-issue-context-failed" });
25334
- setCopiedRuleKey(null);
25335
- setCopyFailedRuleKey(ruleKey);
25336
- });
25337
- };
25338
- useInput((input, key) => {
25339
- if (input === "q") return onQuit();
25340
- if (key.escape) return onBack();
25341
- if (key.return && selected) {
25342
- recordCount(METRIC.tuiReportActionSelected, 1, { action: "copy-issue-context" });
25343
- copySelectedIssueContext();
25344
- }
25345
- });
25346
- let totalFindingCount = 0;
25347
- let errorFindingCount = 0;
25348
- let warningFindingCount = 0;
25349
- for (const row of rows) {
25350
- totalFindingCount += row.siteCount;
25351
- if (row.severity === "error") errorFindingCount += row.siteCount;
25352
- else warningFindingCount += row.siteCount;
25353
- }
25354
- const selectedIssuePosition = entries.slice(0, selectedEntryIndex + 1).filter((entry) => entry.kind === "item").length;
25355
- const unreadIssueCount = rows.length - rows.filter((row) => effectiveReadRuleKeys.has(row.ruleKey)).length;
25356
- const listColumn = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25357
- flexDirection: "column",
25358
- height: listHeight,
25359
- width: isSplit ? listColumnWidth : width,
25360
- children: visibleEntries.map((entry, index) => {
25361
- const entryIndex = visibleEntryStart + index;
25362
- if (entry.kind === "header") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25363
- bold: true,
25364
- children: entry.category
25365
- }, `header-${entry.category}`);
25366
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DiagnosticItem, {
25367
- row: entry.row,
25368
- isSelected: entryIndex === selectedEntryIndex,
25369
- isRead: effectiveReadRuleKeys.has(entry.row.ruleKey)
25370
- }, entry.row.ruleKey);
25371
- })
25372
- });
25373
- let copyFeedback = null;
25374
- if (copiedRuleKey === selectedRuleKey) copyFeedback = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25375
- marginTop: 1,
25376
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25377
- color: "green",
25378
- children: "✓ Copied issue context"
25379
- })
25380
- });
25381
- else if (copyFailedRuleKey === selectedRuleKey) copyFeedback = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25382
- marginTop: 1,
25383
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25384
- color: "yellow",
25385
- children: "Couldn't copy issue context. Press Enter to try again."
25386
- })
25387
- });
25388
- const detailContent = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DiagnosticDetail, {
25389
- row: selected,
25390
- rootDirectory
25391
- }), copyFeedback] });
25392
- let visibleKeyHints = DIAGNOSTIC_KEY_HINTS;
25393
- if (isCompact && copiedRuleKey === selectedRuleKey) visibleKeyHints = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25394
- color: "green",
25395
- children: "✓ Copied issue context"
25396
- });
25397
- else if (isCompact && copyFailedRuleKey === selectedRuleKey) visibleKeyHints = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25398
- color: "yellow",
25399
- children: "Copy failed · enter retry"
25400
- });
25401
- const statusBar = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25402
- marginTop: isCompact ? 0 : 1,
25403
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StatusBar, {
25404
- total: totalFindingCount,
25405
- errorCount: errorFindingCount,
25406
- warningCount: warningFindingCount,
25407
- position: selectedIssuePosition,
25408
- issueCount: rows.length,
25409
- unreadCount: unreadIssueCount,
25410
- projectCount,
25411
- keyHints: visibleKeyHints,
25412
- exitHint,
25413
- compact: isCompact
25414
- })
25415
- });
25416
- if (isCompact) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25417
- flexDirection: "column",
25418
- width,
25419
- children: [
25420
- header,
25421
- listColumn,
25422
- statusBar
25423
- ]
25424
- });
25425
- if (isSplit) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25426
- flexDirection: "column",
25427
- width,
25428
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25429
- flexDirection: "row",
25430
- maxHeight: detailHeight,
25431
- overflowY: "hidden",
25432
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25433
- flexDirection: "column",
25434
- width: listColumnWidth,
25435
- marginRight: 1,
25436
- children: [header, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25437
- marginTop: 1,
25438
- children: listColumn
25439
- })]
25440
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25441
- flexDirection: "column",
25442
- width: detailColumnWidth,
25443
- borderStyle: "single",
25444
- borderColor: "gray",
25445
- borderTop: false,
25446
- borderRight: false,
25447
- borderBottom: false,
25448
- paddingLeft: 1,
25449
- overflowY: "hidden",
25450
- children: detailContent
25451
- })]
25452
- }), statusBar]
25453
- });
25454
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25455
- flexDirection: "column",
25456
- width,
25457
- children: [
25458
- header,
25459
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25460
- marginTop: 1,
25461
- children: listColumn
25462
- }),
25463
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25464
- dimColor: true,
25465
- children: "─".repeat(width)
25466
- }),
25467
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25468
- flexDirection: "column",
25469
- maxHeight: detailHeight,
25470
- overflowY: "hidden",
25471
- children: detailContent
25472
- }),
25473
- statusBar
25474
- ]
25475
- });
25476
- };
25477
- //#endregion
25478
- //#region src/cli/ink/components/handoff-ci-recommendation.tsx
25479
- const HandoffCiRecommendation = ({ onAddToCi, onContinue, onQuit }) => {
25480
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25481
- flexDirection: "column",
25482
- children: [
25483
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25484
- paddingLeft: 2,
25485
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25486
- bold: true,
25487
- children: "Add React Doctor to GitHub Actions first"
25488
- })
25489
- }),
25490
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CiJustification, {}),
25491
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ActionMenu, {
25492
- actions: [{
25493
- id: "add-to-ci",
25494
- label: "Add to GitHub Actions first (Recommended)",
25495
- onSelect: onAddToCi
25496
- }, {
25497
- id: "continue",
25498
- label: "Continue without GitHub Actions",
25499
- onSelect: onContinue
25500
- }],
25501
- onEscape: onContinue,
25502
- onQuit
25503
- }),
25504
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25505
- marginTop: 1,
25506
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25507
- dimColor: true,
25508
- children: "↑/↓ move · enter select · esc skip · q quit"
25509
- })
25510
- })
25511
- ]
25512
- });
25513
- };
25514
- //#endregion
25515
- //#region src/cli/ink/components/report-landing.tsx
25516
- const ReportLanding = ({ header, phase, issueCount, emptyStateMessage, lintFailureReason, skippedChecks, incompleteMessage, actions, selectedIndex, onSelectionChange, onQuit }) => {
25517
- const showScore = phase === "actions" || phase === "score";
25518
- const skippedCheckLabel = skippedChecks?.filter((skippedCheck) => skippedCheck !== "lint" || !lintFailureReason).join(" and ");
25519
- const hasIncompleteResult = Boolean(incompleteMessage || lintFailureReason || skippedCheckLabel);
25520
- useInput((input) => {
25521
- if (input === "q") onQuit();
25522
- }, { isActive: phase !== "actions" });
25523
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25524
- flexDirection: "column",
25525
- children: [
25526
- showScore ? header : null,
25527
- hasIncompleteResult || issueCount === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25528
- flexDirection: "column",
25529
- marginTop: 1,
25530
- children: [
25531
- incompleteMessage ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25532
- color: "yellow",
25533
- children: ["⚠ ", incompleteMessage]
25534
- }) : null,
25535
- lintFailureReason ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25536
- color: "yellow",
25537
- children: ["⚠ Lint did not run: ", lintFailureReason]
25538
- }) : null,
25539
- skippedCheckLabel ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25540
- color: "yellow",
25541
- children: [
25542
- "⚠ ",
25543
- issueCount === 0 ? "No issues detected, but " : "",
25544
- skippedCheckLabel,
25545
- " checks failed — results are incomplete."
25546
- ]
25547
- }) : null,
25548
- issueCount === 0 && !hasIncompleteResult ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25549
- color: "green",
25550
- children: ["✔ ", emptyStateMessage ?? "No issues found. Nice work."]
25551
- }) : null
25552
- ]
25553
- }) : null,
25554
- phase === "actions" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ActionMenu, {
25555
- actions,
25556
- selectedIndex,
25557
- onSelectionChange,
25558
- onEscape: onQuit,
25559
- onQuit
25560
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25561
- marginTop: 1,
25562
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25563
- dimColor: true,
25564
- children: actions.length === 0 ? "q quit" : "↑/↓ move · enter select · q quit"
25565
- })
25566
- })] }) : null
25567
- ]
25568
- });
25569
- };
25570
- //#endregion
25571
- //#region src/cli/ink/components/report-issue-stream.tsx
25572
- const ReportIssueStream = ({ rows, selectedIndex, width }) => {
25573
- const visibleRowCount = Math.min(rows.length, 3);
25574
- const visibleRows = Array.from({ length: visibleRowCount }, (_, visibleRowIndex) => {
25575
- const rowIndex = (selectedIndex - visibleRowCount + visibleRowIndex + 1 + rows.length) % rows.length;
25576
- return {
25577
- row: rows[rowIndex],
25578
- rowIndex
25579
- };
25580
- });
25581
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25582
- flexDirection: "column",
25583
- width: Math.min(width, 60),
25584
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25585
- bold: true,
25586
- children: "Reviewing issues"
25587
- }), visibleRows.map(({ row, rowIndex }) => {
25588
- if (!row) return null;
25589
- const variant = severityVariant(row.severity);
25590
- const isSelected = rowIndex === selectedIndex;
25591
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25592
- dimColor: !isSelected,
25593
- wrap: "truncate-end",
25594
- children: [
25595
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25596
- color: isSelected ? variant.color : void 0,
25597
- children: [isSelected ? "›" : " ", " "]
25598
- }),
25599
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25600
- color: isSelected ? variant.color : void 0,
25601
- bold: isSelected,
25602
- children: [
25603
- row.category,
25604
- ": ",
25605
- row.title
25606
- ]
25607
- }),
25608
- row.siteCount > 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25609
- dimColor: true,
25610
- children: [" ×", row.siteCount]
25611
- }) : null
25612
- ]
25613
- }, row.ruleKey);
25614
- })]
25615
- });
25616
- };
25617
- //#endregion
25618
- //#region src/cli/utils/doctor-face.ts
25619
- const doctorFace = (score) => {
25620
- if (score >= 75) return ["◠ ◠", " ▽ "];
25621
- if (score >= 50) return ["• •", " ─ "];
25622
- return ["x x", " ▽ "];
25623
- };
25624
- //#endregion
25625
- //#region src/cli/utils/ease-out-cubic.ts
25626
- const easeOutCubic = (progress) => 1 - (1 - progress) ** 3;
25627
- //#endregion
25628
- //#region src/cli/ink/hooks/use-animated-score.ts
25629
- const useAnimatedScore = ({ score, projectedScore, shouldAnimate }) => {
25630
- const projectionTarget = projectedScore ?? score;
25631
- const hasProjection = projectionTarget > score;
25632
- const initialProjectedScore = !shouldAnimate && hasProjection ? projectionTarget : null;
25633
- const [displayScore, setDisplayScore] = (0, import_react.useState)(shouldAnimate ? 0 : score);
25634
- const [displayProjectedScore, setDisplayProjectedScore] = (0, import_react.useState)(initialProjectedScore);
25635
- (0, import_react.useEffect)(() => {
25636
- if (!shouldAnimate) {
25637
- setDisplayScore(score);
25638
- setDisplayProjectedScore(hasProjection ? projectionTarget : null);
25639
- return;
25640
- }
25641
- let timeoutId;
25642
- const runProjection = () => {
25643
- let projectionFrame = 1;
25644
- const renderProjectionFrame = () => {
25645
- const progress = easeOutCubic(projectionFrame / 16);
25646
- setDisplayProjectedScore(score + (projectionTarget - score) * progress);
25647
- if (projectionFrame < 16) {
25648
- projectionFrame += 1;
25649
- timeoutId = setTimeout(renderProjectionFrame, 35);
25650
- } else setDisplayProjectedScore(projectionTarget);
25651
- };
25652
- renderProjectionFrame();
25653
- };
25654
- let scoreFrame = 0;
25655
- const renderScoreFrame = () => {
25656
- const progress = easeOutCubic(scoreFrame / 40);
25657
- setDisplayScore(Math.round(score * progress));
25658
- if (scoreFrame < 40) {
25659
- scoreFrame += 1;
25660
- timeoutId = setTimeout(renderScoreFrame, 50);
25661
- return;
25662
- }
25663
- setDisplayScore(score);
25664
- if (hasProjection) runProjection();
25665
- };
25666
- renderScoreFrame();
25667
- return () => {
25668
- if (timeoutId !== void 0) clearTimeout(timeoutId);
25669
- };
25670
- }, [
25671
- shouldAnimate,
25672
- score,
25673
- projectionTarget,
25674
- hasProjection
25675
- ]);
25676
- return {
25677
- displayScore,
25678
- displayProjectedScore
25679
- };
25680
- };
25681
- //#endregion
25682
- //#region src/cli/ink/lib/score-color.ts
25683
- const scoreColorName = (score) => {
25684
- if (score >= 75) return "green";
25685
- if (score >= 50) return "yellow";
25686
- return "red";
25687
- };
25688
- //#endregion
25689
- //#region src/cli/ink/components/score-header.tsx
25690
- const REACT_DOCTOR_URL = "https://react.doctor";
25691
- const ReactDoctorLink = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TuiLink, {
25692
- url: REACT_DOCTOR_URL,
25693
- children: ["React Doctor ", /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25694
- dimColor: true,
25695
- children: [
25696
- "(",
25697
- REACT_DOCTOR_URL,
25698
- ")"
25699
- ]
25700
- })]
25701
- });
25702
- const ScoreHeader = ({ variant, score, projectedScore, projectName, issueCount, noScoreMessage, width }) => {
25703
- const { columns } = useStdoutDimensions();
25704
- const availableWidth = width ?? columns;
25705
- const { stdout } = useStdout();
25706
- const shouldAnimateScore = canAnimateOnboarding(stdout ?? void 0);
25707
- const visibleProjectedScore = variant === "landing" ? projectedScore : null;
25708
- const { displayScore, displayProjectedScore } = useAnimatedScore({
25709
- score: score?.score ?? 0,
25710
- projectedScore: visibleProjectedScore,
25711
- shouldAnimate: variant === "landing" && shouldAnimateScore && score !== null
25712
- });
25713
- if (!score) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25714
- flexDirection: "column",
25715
- paddingLeft: 2,
25716
- width: availableWidth,
25717
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25718
- wrap: "truncate-end",
25719
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReactDoctorLink, {})
25720
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25721
- dimColor: true,
25722
- wrap: "wrap",
25723
- children: noScoreMessage ?? `${pluralize(issueCount, "finding")} · ${projectName}`
25724
- })]
25725
- });
25726
- const scoreColor = scoreColorName(score.score);
25727
- const scoreSummaryLine = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25728
- wrap: "truncate-end",
25729
- children: [
25730
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25731
- color: scoreColor,
25732
- bold: true,
25733
- children: displayScore
25734
- }),
25735
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25736
- dimColor: true,
25737
- children: [
25738
- " / ",
25739
- 100,
25740
- " "
25741
- ]
25742
- }),
25743
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25744
- color: scoreColor,
25745
- children: score.label
25746
- }),
25747
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25748
- dimColor: true,
25749
- children: [" · ", projectName]
25750
- })
25751
- ]
25752
- });
25753
- if (availableWidth < 23) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25754
- flexDirection: "column",
25755
- width: availableWidth,
25756
- children: [scoreSummaryLine, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25757
- wrap: "truncate-end",
25758
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReactDoctorLink, {})
25759
- })]
25760
- });
25761
- const barWidth = Math.max(10, Math.min(50, availableWidth - 11 - 2));
25762
- const filledBarWidth = Math.round(displayScore / 100 * barWidth);
25763
- const projectedBarWidth = displayProjectedScore != null ? Math.min(barWidth, Math.round(displayProjectedScore / 100 * barWidth)) : filledBarWidth;
25764
- const projectedGainWidth = Math.max(0, projectedBarWidth - filledBarWidth);
25765
- const emptyBarWidth = Math.max(0, barWidth - filledBarWidth - projectedGainWidth);
25766
- const [eyes, mouth] = doctorFace(score.score);
25767
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25768
- flexDirection: "column",
25769
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25770
- paddingLeft: 2,
25771
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
25772
- flexDirection: "column",
25773
- marginRight: 2,
25774
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25775
- color: scoreColor,
25776
- children: `┌─────┐\n│ ${eyes} │\n│ ${mouth} │\n└─────┘`
25777
- })
25778
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
25779
- flexDirection: "column",
25780
- children: [
25781
- scoreSummaryLine,
25782
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25783
- wrap: "truncate-end",
25784
- children: [
25785
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25786
- color: scoreColor,
25787
- children: "█".repeat(filledBarWidth)
25788
- }),
25789
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25790
- color: scoreColor,
25791
- dimColor: true,
25792
- children: "▓".repeat(projectedGainWidth)
25793
- }),
25794
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25795
- dimColor: true,
25796
- children: "░".repeat(emptyBarWidth)
25797
- })
25798
- ]
25799
- }),
25800
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25801
- wrap: "truncate-end",
25802
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReactDoctorLink, {})
25803
- }),
25804
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: " " })
25805
- ]
25806
- })]
25807
- }), variant === "landing" && projectedScore != null && projectedScore > score.score ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25808
- wrap: "truncate-end",
25809
- children: [
25810
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25811
- dimColor: true,
25812
- children: " Potential score "
25813
- }),
25814
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25815
- color: scoreColorName(projectedScore),
25816
- children: projectedScore
25817
- }),
25818
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
25819
- dimColor: true,
25820
- children: " after priority fixes "
25821
- }),
25822
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
25823
- color: scoreColorName(projectedScore),
25824
- children: ["+", projectedScore - score.score]
25825
- })
25826
- ]
25827
- }) : null]
25828
- });
25829
- };
25830
- //#endregion
25831
- //#region src/cli/ink/components/report.tsx
25832
- const EMPTY_LAUNCHABLE_AGENTS = [];
25833
- const recordReportAction = (action) => {
25834
- recordCount(METRIC.tuiReportActionSelected, 1, { action });
25835
- };
25836
- const completeReportOnboarding = () => {
25837
- if (shouldRecordOnboarding({
25838
- paceOnboardingSections: true,
25839
- forceOnboarding: isOnboardingForced(),
25840
- verbose: false,
25841
- isNonInteractiveEnvironment: false
25842
- })) markOnboardingComplete();
25843
- };
25844
- const Report = ({ report, onExit, onQuit = onExit, launchableAgents = EMPTY_LAUNCHABLE_AGENTS, onHandoff, canAddToCi, onAddToCi, projectCount, priorityScores, exitHint = "q to quit" }) => {
25845
- const { rows: terminalRows, columns } = useStdoutDimensions();
25846
- const diagnosticRows = (0, import_react.useMemo)(() => buildDiagnosticRows(report.diagnostics, priorityScores ?? [report.score]), [
25847
- report.diagnostics,
25848
- report.score,
25849
- priorityScores
25850
- ]);
25851
- const diagnosticListEntries = (0, import_react.useMemo)(() => buildDiagnosticListEntries(diagnosticRows), [diagnosticRows]);
25852
- const reportLayout = resolveReportLayout({
25853
- columns,
25854
- diagnosticEntryCount: diagnosticListEntries.length,
25855
- terminalRows
25856
- });
25857
- const reportReveal = useReportReveal({
25858
- issueCount: diagnosticRows.length,
25859
- onRevealComplete: completeReportOnboarding
25860
- });
25861
- const [activeReportScreen, setActiveReportScreen] = (0, import_react.useState)("landing");
25862
- const [ciSetupFeedback, setCiSetupFeedback] = (0, import_react.useState)();
25863
- const [landingSelectedIndex, setLandingSelectedIndex] = (0, import_react.useState)(0);
25864
- const [viewerSelectedRowIndex, setViewerSelectedRowIndex] = (0, import_react.useState)(null);
25865
- const [viewerReadRuleKeys, setViewerReadRuleKeys] = (0, import_react.useState)(() => /* @__PURE__ */ new Set());
25866
- const [isCiSetupQueued, setIsCiSetupQueued] = (0, import_react.useState)(false);
25867
- const [shouldShowIssueStream, setShouldShowIssueStream] = (0, import_react.useState)(true);
25868
- const didRecordCompactReport = (0, import_react.useRef)(false);
25869
- const didRecordIssueStream = (0, import_react.useRef)(false);
25870
- const didRecordStackedReportCap = (0, import_react.useRef)(false);
25871
- const isCompact = reportLayout.layout === "compact";
25872
- const isWide = reportLayout.layout === "split";
25873
- (0, import_react.useEffect)(() => {
25874
- if (!isCompact || didRecordCompactReport.current) return;
25875
- didRecordCompactReport.current = true;
25876
- recordCount(METRIC.tuiCompactReportShown);
25877
- }, [isCompact]);
25878
- (0, import_react.useEffect)(() => {
25879
- if (!reportLayout.isStackedReportCapped || didRecordStackedReportCap.current) return;
25880
- didRecordStackedReportCap.current = true;
25881
- recordCount(METRIC.tuiStackedReportCapped);
25882
- }, [reportLayout.isStackedReportCapped]);
25883
- (0, import_react.useEffect)(() => {
25884
- if (reportReveal.phase !== "streaming" || didRecordIssueStream.current) return;
25885
- didRecordIssueStream.current = true;
25886
- recordCount(METRIC.tuiIssueStreamShown);
25887
- }, [reportReveal.phase]);
25888
- const scoreHeaderProps = {
25889
- score: report.score,
25890
- projectedScore: report.projectedScore,
25891
- projectName: report.projectName,
25892
- issueCount: report.diagnostics.length,
25893
- noScoreMessage: report.noScoreMessage,
25894
- width: isWide ? reportLayout.listColumnWidth : reportLayout.width
25895
- };
25896
- const isCiSetupAvailable = Boolean(canAddToCi && onAddToCi && !isCiSetupQueued);
25897
- const isHandoffAvailable = diagnosticRows.length > 0 && launchableAgents.length > 0 && Boolean(onHandoff);
25898
- const firstDiagnosticEntry = diagnosticListEntries.find((entry) => entry.kind === "item");
25899
- const resolvedViewerSelectedRowIndex = viewerSelectedRowIndex ?? (firstDiagnosticEntry?.kind === "item" ? firstDiagnosticEntry.rowIndex : null);
25900
- const markViewerRuleRead = (index) => {
25901
- const ruleKey = diagnosticRows[index]?.ruleKey;
25902
- if (!ruleKey) return;
25903
- setViewerReadRuleKeys((previous) => previous.has(ruleKey) ? previous : new Set(previous).add(ruleKey));
25904
- };
25905
- const handleViewerSelectionChange = (index) => {
25906
- setViewerSelectedRowIndex(index);
25907
- markViewerRuleRead(index);
25908
- };
25909
- const openReportScreen = (nextScreen) => {
25910
- setShouldShowIssueStream(false);
25911
- setCiSetupFeedback(void 0);
25912
- setActiveReportScreen(nextScreen);
25913
- };
25914
- const landingActions = [];
25915
- if (report.diagnostics.length > 0) landingActions.push({
25916
- id: "view-issues",
25917
- label: `Review ${pluralize(diagnosticRows.length, "issue")}`,
25918
- onSelect: () => {
25919
- recordReportAction("view-issues");
25920
- if (resolvedViewerSelectedRowIndex !== null) {
25921
- setViewerSelectedRowIndex(resolvedViewerSelectedRowIndex);
25922
- markViewerRuleRead(resolvedViewerSelectedRowIndex);
25923
- }
25924
- openReportScreen("issues");
25925
- }
25926
- });
25927
- if (isCiSetupAvailable) landingActions.push({
25928
- id: "add-to-ci",
25929
- label: "Add to GitHub Actions (Recommended)",
25930
- description: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CiJustification, {}),
25931
- onSelect: () => {
25932
- recordReportAction("add-to-ci");
25933
- openReportScreen("ci");
25934
- }
25935
- });
25936
- if (isHandoffAvailable) landingActions.push({
25937
- id: "handoff",
25938
- label: "Hand off to an agent",
25939
- onSelect: () => {
25940
- recordReportAction("handoff");
25941
- openReportScreen(isCiSetupAvailable ? "handoff-ci" : "handoff");
25942
- }
25943
- });
25944
- const postReviewLandingActionIndex = landingActions.findIndex((action) => action.id !== "view-issues");
25945
- const resolvedLandingSelectedIndex = Math.min(landingSelectedIndex, Math.max(0, landingActions.length - 1));
25946
- const issueStream = reportReveal.phase === "streaming" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReportIssueStream, {
25947
- rows: diagnosticRows,
25948
- selectedIndex: reportReveal.streamSelectedIndex,
25949
- width: reportLayout.width
25950
- }) : null;
25951
- let activeScreenContent;
25952
- if (activeReportScreen === "ci") activeScreenContent = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CiSetup, {
25953
- feedback: ciSetupFeedback,
25954
- onConfirm: () => {
25955
- onAddToCi?.();
25956
- onExit();
25957
- },
25958
- onLearnMore: () => {
25959
- recordReportAction("ci-learn-more");
25960
- openUrl(GITHUB_ACTIONS_SETUP_URL).then((didOpen) => {
25961
- setCiSetupFeedback({
25962
- didSucceed: didOpen,
25963
- message: didOpen ? "✓ Opened the GitHub Actions guide in your browser" : `Couldn't open a browser. Visit ${GITHUB_ACTIONS_SETUP_URL}`
25964
- });
25965
- });
25966
- },
25967
- onBack: () => {
25968
- setCiSetupFeedback(void 0);
25969
- setActiveReportScreen("landing");
25970
- },
25971
- onQuit
25972
- });
25973
- else if (activeReportScreen === "handoff") activeScreenContent = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AgentHandoff, {
25974
- agents: launchableAgents,
25975
- onSelect: (agentId) => {
25976
- if (!onHandoff) return;
25977
- onHandoff({
25978
- agentId,
25979
- prompt: buildHandoffPayload({
25980
- diagnostics: report.diagnostics,
25981
- projectName: report.projectName
25982
- })
25983
- });
25984
- onExit();
25985
- },
25986
- onBack: () => setActiveReportScreen("landing"),
25987
- onQuit
25988
- });
25989
- else if (activeReportScreen === "handoff-ci") activeScreenContent = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HandoffCiRecommendation, {
25990
- onAddToCi: () => {
25991
- onAddToCi?.();
25992
- setIsCiSetupQueued(true);
25993
- setActiveReportScreen("handoff");
25994
- },
25995
- onContinue: () => setActiveReportScreen("handoff"),
25996
- onQuit
25997
- });
25998
- else if (activeReportScreen === "landing") activeScreenContent = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReportLanding, {
25999
- header: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScoreHeader, {
26000
- variant: "landing",
26001
- ...scoreHeaderProps
26002
- }),
26003
- phase: reportReveal.phase,
26004
- issueCount: report.diagnostics.length,
26005
- emptyStateMessage: report.emptyStateMessage,
26006
- lintFailureReason: report.lintFailureReason,
26007
- skippedChecks: report.skippedChecks,
26008
- incompleteMessage: report.incompleteMessage,
26009
- actions: landingActions,
26010
- selectedIndex: resolvedLandingSelectedIndex,
26011
- onSelectionChange: setLandingSelectedIndex,
26012
- onQuit
26013
- });
26014
- else activeScreenContent = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DiagnosticList, {
26015
- header: reportLayout.showsViewerScoreHeader ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScoreHeader, {
26016
- variant: "viewer",
26017
- ...scoreHeaderProps
26018
- }) : null,
26019
- rows: diagnosticRows,
26020
- entries: diagnosticListEntries,
26021
- width: reportLayout.width,
26022
- listColumnWidth: reportLayout.listColumnWidth,
26023
- detailColumnWidth: reportLayout.detailColumnWidth,
26024
- listHeight: reportLayout.listHeight,
26025
- detailHeight: reportLayout.detailHeight,
26026
- layout: reportLayout.layout,
26027
- rootDirectory: report.rootDirectory,
26028
- projectName: report.projectName,
26029
- projectCount,
26030
- initialSelectedRowIndex: resolvedViewerSelectedRowIndex,
26031
- readRuleKeys: viewerReadRuleKeys,
26032
- onSelectedRowIndexChange: handleViewerSelectionChange,
26033
- onQuit,
26034
- onBack: () => {
26035
- setLandingSelectedIndex(Math.max(0, postReviewLandingActionIndex));
26036
- setActiveReportScreen("landing");
26037
- },
26038
- exitHint: `esc back · ${exitHint}`
26039
- });
26040
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [activeReportScreen === "landing" && shouldShowIssueStream ? issueStream : null, activeScreenContent] });
26041
- };
26042
- //#endregion
26043
23958
  //#region ../../node_modules/.pnpm/cli-spinners@2.9.2/node_modules/cli-spinners/spinners.json
26044
23959
  var require_spinners = /* @__PURE__ */ __commonJSMin(((exports, module) => {
26045
23960
  module.exports = {
@@ -27652,232 +25567,52 @@ function Spinner({ type = "dots" }) {
27652
25567
  return import_react.createElement(Text, null, spinner.frames[frame]);
27653
25568
  }
27654
25569
  //#endregion
27655
- //#region src/cli/ink/components/scanning.tsx
27656
- const Scanning = ({ progressText, recent }) => {
27657
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
27658
- flexDirection: "column",
27659
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
27660
- wrap: "truncate-end",
27661
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
27662
- color: "cyan",
27663
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { type: "dots" })
27664
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [" ", progressText ?? "Scanning…"] })]
27665
- }), recent.map((diagnostic, diagnosticIndex) => {
27666
- const variant = severityVariant(diagnostic.severity === "error" ? "error" : "warning");
27667
- const location = formatDiagnosticSite(diagnostic);
27668
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
27669
- wrap: "truncate-end",
27670
- children: [
27671
- " ",
27672
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
27673
- color: variant.color,
27674
- children: variant.icon
27675
- }),
27676
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [" ", diagnostic.title ?? `${diagnostic.plugin}/${diagnostic.rule}`] }),
27677
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
27678
- dimColor: true,
27679
- children: [" ", location]
27680
- })
27681
- ]
27682
- }, `${diagnostic.filePath}:${diagnostic.line}:${diagnostic.column}:${diagnostic.plugin}:${diagnostic.rule}:${diagnosticIndex}`);
27683
- })]
27684
- });
27685
- };
25570
+ //#region src/cli/utils/is-printable-input.ts
25571
+ const isPrintableInput = (input) => input.length > 0 && [...input].every((character) => character.charCodeAt(0) >= 32);
27686
25572
  //#endregion
27687
- //#region src/cli/ink/components/summary.tsx
27688
- const Summary = ({ summary, onExit, onQuit, launchableAgents, onHandoff, canAddToCi, onAddToCi }) => {
27689
- const skippedProjects = summary.skippedProjects ?? [];
27690
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Report, {
27691
- report: {
27692
- diagnostics: summary.combinedDiagnostics,
27693
- score: summary.aggregateScore,
27694
- projectedScore: summary.projectedScore,
27695
- projectName: summary.projectName,
27696
- rootDirectory: summary.rootDirectory,
27697
- scannedFileCount: summary.scannedFileCount,
27698
- elapsedMilliseconds: summary.elapsedMilliseconds,
27699
- isOffline: summary.isOffline,
27700
- noScoreMessage: summary.noScoreMessage,
27701
- skippedChecks: [...new Set(summary.projects.flatMap((project) => project.skippedChecks ?? []))],
27702
- ...skippedProjects.length > 0 ? { incompleteMessage: formatSkippedProjectsMessage(skippedProjects.length) } : {},
27703
- ...summary.emptyStateMessage ? { emptyStateMessage: summary.emptyStateMessage } : {},
27704
- ...summary.lintFailureReason ? { lintFailureReason: summary.lintFailureReason } : {}
27705
- },
27706
- onExit,
27707
- onQuit,
27708
- launchableAgents,
27709
- onHandoff,
27710
- canAddToCi,
27711
- onAddToCi,
27712
- projectCount: summary.projects.length + skippedProjects.length,
27713
- priorityScores: summary.projects.map((project) => project.score)
27714
- });
25573
+ //#region src/cli/utils/terminal-symbols.ts
25574
+ const supportsUnicodeSymbols = process.platform !== "win32" ? process.env.TERM !== "linux" : Boolean(process.env.WT_SESSION) || Boolean(process.env.TERMINUS_SUBLIME) || process.env.ConEmuTask === "{cmd::Cmder}" || process.env.TERM_PROGRAM === "Terminus-Sublime" || process.env.TERM_PROGRAM === "vscode" || process.env.TERM === "xterm-256color" || process.env.TERM === "alacritty" || process.env.TERM === "rxvt-unicode" || process.env.TERM === "rxvt-unicode-256color" || process.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
25575
+ const terminalSymbols = {
25576
+ pointer: supportsUnicodeSymbols ? "❯" : ">",
25577
+ pointerSmall: "›",
25578
+ radioOn: supportsUnicodeSymbols ? "◉" : "(*)",
25579
+ radioOff: supportsUnicodeSymbols ? "◯" : "( )"
27715
25580
  };
27716
25581
  //#endregion
27717
- //#region src/cli/ink/hooks/use-scan-store.ts
27718
- const useScanStore = (store) => (0, import_react.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getSnapshot);
27719
- //#endregion
27720
- //#region src/cli/ink/scan-app.tsx
27721
- const ScanApp = ({ store, displayMode = "report", launchableAgents, onHandoff, canAddToCi, onAddToCi, onQuit }) => {
27722
- const snapshot = useScanStore(store);
27723
- const { exit } = useApp();
27724
- useExitOnCtrlC(onQuit);
27725
- const handleQuit = () => {
27726
- onQuit?.();
27727
- exit();
27728
- };
27729
- if (displayMode === "report" && snapshot.phase === "summary") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Summary, {
27730
- summary: snapshot.summary,
27731
- launchableAgents,
27732
- onHandoff,
27733
- canAddToCi,
27734
- onAddToCi,
27735
- onExit: exit,
27736
- onQuit: handleQuit
27737
- });
27738
- if (displayMode === "report" && snapshot.phase === "report") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Report, {
27739
- report: snapshot.report,
27740
- launchableAgents,
27741
- onHandoff,
27742
- canAddToCi,
27743
- onAddToCi,
27744
- onExit: exit,
27745
- onQuit: handleQuit
27746
- });
27747
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Scanning, {
27748
- progressText: snapshot.progress,
27749
- recent: snapshot.liveDiagnostics.slice(-5)
25582
+ //#region src/cli/ink/hooks/use-exit-on-ctrl-c.ts
25583
+ const SHOW_CURSOR = "\x1B[?25h";
25584
+ const useExitOnCtrlC = (onCancel) => {
25585
+ useInput((input, key) => {
25586
+ if (key.ctrl && input === "c") {
25587
+ onCancel?.();
25588
+ recordCount(METRIC.tuiCancelled, 1, { resourceFooter: true });
25589
+ process.stdin.setRawMode?.(false);
25590
+ process.stdout.write(SHOW_CURSOR);
25591
+ exitGracefully();
25592
+ }
27750
25593
  });
27751
25594
  };
27752
25595
  //#endregion
27753
- //#region src/cli/ink/scan-bridge-layers.ts
27754
- const reporterLayerForStore = (store) => succeed(Reporter, Reporter.of({
27755
- emit: (diagnostic) => sync(() => store.emitDiagnostic(diagnostic)),
27756
- finalize: void_
27757
- }));
27758
- const progressHandleForStore = (store, options = {}) => (text) => {
27759
- const transformText = options.transformText ?? ((displayText) => displayText);
27760
- store.setProgress(transformText(text));
27761
- return {
27762
- update: (displayText) => sync(() => store.scheduleProgress(transformText(displayText))),
27763
- succeed: (displayText) => sync(() => store.setProgress(transformText(displayText))),
27764
- fail: (displayText) => sync(() => store.setProgress(transformText(displayText))),
27765
- stop: () => sync(() => store.setProgress(options.shouldClearOnStop === false ? transformText(text) : null))
27766
- };
27767
- };
27768
- const progressLayerForStore = (store, options = {}) => Progress.layerOra(progressHandleForStore(store, options));
27769
- //#endregion
27770
- //#region src/cli/ink/scan-store.ts
27771
- const INITIAL_SNAPSHOT = {
27772
- phase: "scanning",
27773
- liveDiagnostics: [],
27774
- progress: null
27775
- };
27776
- const createScanStore = () => {
27777
- let snapshot = INITIAL_SNAPSHOT;
27778
- const listeners = /* @__PURE__ */ new Set();
27779
- let pendingProgress = null;
27780
- let progressTimer = null;
27781
- const commit = (next) => {
27782
- snapshot = next;
27783
- for (const listener of [...listeners]) listener();
27784
- };
27785
- const cancelPendingProgress = () => {
27786
- pendingProgress = null;
27787
- if (progressTimer === null) return;
27788
- clearTimeout(progressTimer);
27789
- progressTimer = null;
27790
- };
27791
- const setProgress = (progress) => {
27792
- cancelPendingProgress();
27793
- commit({
27794
- ...snapshot,
27795
- progress
27796
- });
27797
- };
27798
- return {
27799
- subscribe: (listener) => {
27800
- listeners.add(listener);
27801
- return () => {
27802
- listeners.delete(listener);
27803
- };
27804
- },
27805
- getSnapshot: () => snapshot,
27806
- emitDiagnostic: (diagnostic) => commit({
27807
- ...snapshot,
27808
- liveDiagnostics: [...snapshot.liveDiagnostics, diagnostic].slice(-25)
27809
- }),
27810
- scheduleProgress: (progress) => {
27811
- pendingProgress = progress;
27812
- if (progressTimer !== null) return;
27813
- progressTimer = setTimeout(() => {
27814
- progressTimer = null;
27815
- const progressToCommit = pendingProgress;
27816
- pendingProgress = null;
27817
- if (progressToCommit !== null) commit({
27818
- ...snapshot,
27819
- progress: progressToCommit
27820
- });
27821
- }, 250);
27822
- progressTimer.unref?.();
27823
- },
27824
- setProgress,
27825
- setReport: (report) => {
27826
- cancelPendingProgress();
27827
- commit({
27828
- phase: "report",
27829
- liveDiagnostics: snapshot.liveDiagnostics,
27830
- progress: snapshot.progress,
27831
- report
27832
- });
27833
- },
27834
- setSummary: (summary) => {
27835
- cancelPendingProgress();
27836
- commit({
27837
- phase: "summary",
27838
- liveDiagnostics: snapshot.liveDiagnostics,
27839
- progress: snapshot.progress,
27840
- summary
27841
- });
27842
- }
27843
- };
25596
+ //#region src/cli/ink/hooks/use-stdout-dimensions.ts
25597
+ const readDimensions = (stdout) => ({
25598
+ columns: stdout?.columns ?? 80,
25599
+ rows: stdout?.rows ?? 24
25600
+ });
25601
+ const useStdoutDimensions = () => {
25602
+ const { stdout } = useStdout();
25603
+ const [dimensions, setDimensions] = (0, import_react.useState)(() => readDimensions(stdout));
25604
+ (0, import_react.useEffect)(() => {
25605
+ if (!stdout) return;
25606
+ const onResize = () => setDimensions(readDimensions(stdout));
25607
+ stdout.on("resize", onResize);
25608
+ return () => {
25609
+ stdout.off("resize", onResize);
25610
+ };
25611
+ }, [stdout]);
25612
+ return dimensions;
27844
25613
  };
27845
25614
  //#endregion
27846
- //#region src/cli/ink/run-scan-app.tsx
27847
- const qualifyDiagnosticPaths = (diagnostics, rootDirectory, projectDirectory) => {
27848
- const prefix = path.relative(rootDirectory, projectDirectory);
27849
- if (prefix === "" || prefix.startsWith("..")) return [...diagnostics];
27850
- return diagnostics.map((diagnostic) => path.isAbsolute(diagnostic.filePath) ? diagnostic : {
27851
- ...diagnostic,
27852
- filePath: toForwardSlashes(path.join(prefix, diagnostic.filePath))
27853
- });
27854
- };
27855
- const resolveScanPresentation = (input, projectScans) => {
27856
- const isScoreDisabled = input.options?.noScore === true || projectScans.some((projectScan) => projectScan.config?.noScore === true);
27857
- return {
27858
- isOffline: isCiEnvironment() || input.share === false || isShareOptedOut(projectScans, input.options?.noScore),
27859
- initialProgress: projectScans.length > 1 ? "Indexing workspace files…" : "Scanning project…",
27860
- noScoreMessage: buildNoScoreMessage({ isScoreDisabled }),
27861
- outputDirectory: input.options?.outputDirectory,
27862
- shouldRecommendCi: projectScans.length > 1 || projectScans.some((projectScan) => isCiUnconfigured(projectScan.directory)),
27863
- verbose: input.options?.verbose === true
27864
- };
27865
- };
27866
- const resolveTuiInspectOptions = (input, config) => {
27867
- const warnings = resolveCliInspectOptions({
27868
- blocking: input.blocking,
27869
- warnings: input.options?.warnings
27870
- }, config).warnings;
27871
- return warnings === void 0 ? { ...input.options } : {
27872
- ...input.options,
27873
- warnings
27874
- };
27875
- };
27876
- const resolveSelectedDirectories = async (rootDirectory, input) => {
27877
- const packages = discoverWorkspacePackages(rootDirectory);
27878
- if (!(packages.length > 1 && !input.projectFlag && !input.skipPrompts && (input.configProjects ?? []).length === 0 && process.stdin.isTTY === true)) return selectProjects(rootDirectory, input.projectFlag, input.skipPrompts ?? false, input.configProjects);
27879
- return promptProjectSelection(packages, rootDirectory);
27880
- };
25615
+ //#region src/cli/ink/register-mounted-tui-renderer.ts
27881
25616
  const registerMountedTuiRenderer = (instance) => {
27882
25617
  let didDisposeRenderer = false;
27883
25618
  const disposeRenderer = (shouldClearOutput) => {
@@ -27892,427 +25627,247 @@ const registerMountedTuiRenderer = (instance) => {
27892
25627
  disposeRenderer(true);
27893
25628
  };
27894
25629
  };
27895
- const promptProjectSelection = (packages, rootDirectory) => new Promise((resolve) => {
27896
- let disposeRenderer = () => {};
27897
- recordCount(METRIC.tuiProjectSelectShown);
27898
- disposeRenderer = registerMountedTuiRenderer(render(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProjectSelect, {
27899
- packages,
27900
- rootDirectory,
27901
- onSubmit: (directories) => {
27902
- disposeRenderer();
27903
- resolve(directories);
27904
- }
27905
- }), {
27906
- alternateScreen: true,
27907
- exitOnCtrlC: false
27908
- }));
27909
- });
27910
- const resolveLintFailureReason = (results) => {
27911
- for (const result of results) {
27912
- if (!hasLintHardFailure(result)) continue;
27913
- return result.skippedCheckReasons?.lint ?? "Lint failed before diagnostics were produced.";
27914
- }
27915
- return null;
27916
- };
27917
- const toScanReport = ({ result, diagnostics, rootDirectory, projectedScore, isOffline, noScoreMessage, emptyStateMessage }) => {
27918
- const lintFailureReason = resolveLintFailureReason([result]);
27919
- return {
27920
- diagnostics: diagnostics ?? result.diagnostics,
27921
- score: result.score,
27922
- projectedScore,
27923
- projectName: result.project.projectName,
27924
- rootDirectory,
27925
- scannedFileCount: result.scannedFileCount ?? 0,
27926
- elapsedMilliseconds: result.elapsedMilliseconds,
27927
- isOffline,
27928
- noScoreMessage,
27929
- emptyStateMessage,
27930
- skippedChecks: result.skippedChecks,
27931
- ...lintFailureReason ? { lintFailureReason } : {}
27932
- };
27933
- };
27934
- const findLowestScoredReport = (reports) => {
27935
- let lowestScoredReport = null;
27936
- for (const report of reports) {
27937
- if (report.score === null) continue;
27938
- if (lowestScoredReport === null || report.score.score < lowestScoredReport.score.score) lowestScoredReport = {
27939
- score: report.score,
27940
- scoreDiagnostics: report.scoreDiagnostics
27941
- };
27942
- }
27943
- return lowestScoredReport;
27944
- };
27945
- const resolveEmptyStateMessage = (input, demotedDiagnosticCount) => buildEmptyReportMessage({
27946
- categoryFilters: input.options?.categoryFilters ?? [],
27947
- demotedDiagnosticCount,
27948
- outputSurface: input.options?.outputSurface ?? "cli"
27949
- });
27950
- const printExitFooter = async (input) => {
27951
- process.stdout.write(`${highlighter.success("✔")} Scanned ${pluralize(input.scannedFileCount, "file")} in ${formatElapsedTime(input.elapsedMilliseconds)}\n`);
27952
- if (input.lintFailureReason !== null) process.stdout.write(`${highlighter.warn("⚠")} Lint did not run: ${input.lintFailureReason}\n`);
27953
- await runPromise(printFooter({
27954
- diagnostics: [...input.diagnostics],
27955
- scoreResult: input.scoreResult,
27956
- projectName: input.projectName,
27957
- isOffline: input.isOffline
27958
- }));
27959
- };
27960
- const performTuiHandoff = async (request, rootDirectory) => {
27961
- try {
27962
- await launchCliAgent(request.agentId, request.prompt, rootDirectory);
27963
- } catch {
27964
- process.stdout.write(`${highlighter.warn("⚠")} Couldn't launch ${CLI_AGENT_BINARIES[request.agentId]}. Here's the prompt instead:\n`);
27965
- process.stdout.write(`${highlighter.dim("──── Agent prompt ────")}\n`);
27966
- process.stdout.write(`${request.prompt}\n`);
27967
- process.stdout.write(`${highlighter.dim("──────────────────────")}\n`);
27968
- }
27969
- };
27970
- const isCiUnconfigured = (directory) => !isReactDoctorWorkflowInstalled(findNearestPackageDirectory(directory) ?? directory);
27971
- const performCiSetup = async (rootDirectory) => {
27972
- const didCreateWorkflow = await setUpGitHubActions({ rootDirectory });
27973
- recordCount(METRIC.agentHandoff, 1, {
27974
- outcome: "ci-yes",
27975
- source: "tui",
27976
- created: didCreateWorkflow
27977
- });
27978
- };
27979
- const mountScanApp = async (rootDirectory, shouldRecommendCi, initialProgress) => {
27980
- const store = createScanStore();
27981
- store.setProgress(initialProgress);
27982
- const launchableAgents = await detectLaunchableAgents();
27983
- const pendingActions = {
27984
- handoffRequest: null,
27985
- shouldSetUpCi: false,
27986
- didQuit: false
27987
- };
27988
- const mountRenderer = (displayMode) => {
27989
- const instance = render(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScanApp, {
27990
- store,
27991
- displayMode,
27992
- launchableAgents,
27993
- onHandoff: (request) => {
27994
- pendingActions.handoffRequest = request;
27995
- },
27996
- canAddToCi: shouldRecommendCi,
27997
- onAddToCi: () => {
27998
- pendingActions.shouldSetUpCi = true;
27999
- },
28000
- onQuit: () => {
28001
- pendingActions.didQuit = true;
28002
- }
28003
- }), {
28004
- alternateScreen: false,
28005
- exitOnCtrlC: false
28006
- });
25630
+ //#endregion
25631
+ //#region ../../node_modules/.pnpm/react@19.2.5/node_modules/react/cjs/react-jsx-runtime.production.js
25632
+ /**
25633
+ * @license React
25634
+ * react-jsx-runtime.production.js
25635
+ *
25636
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
25637
+ *
25638
+ * This source code is licensed under the MIT license found in the
25639
+ * LICENSE file in the root directory of this source tree.
25640
+ */
25641
+ var require_react_jsx_runtime_production = /* @__PURE__ */ __commonJSMin(((exports) => {
25642
+ var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment");
25643
+ function jsxProd(type, config, maybeKey) {
25644
+ var key = null;
25645
+ void 0 !== maybeKey && (key = "" + maybeKey);
25646
+ void 0 !== config.key && (key = "" + config.key);
25647
+ if ("key" in config) {
25648
+ maybeKey = {};
25649
+ for (var propName in config) "key" !== propName && (maybeKey[propName] = config[propName]);
25650
+ } else maybeKey = config;
25651
+ config = maybeKey.ref;
28007
25652
  return {
28008
- instance,
28009
- dispose: registerMountedTuiRenderer(instance)
25653
+ $$typeof: REACT_ELEMENT_TYPE,
25654
+ type,
25655
+ key,
25656
+ ref: void 0 !== config ? config : null,
25657
+ props: maybeKey
28010
25658
  };
28011
- };
28012
- const executePendingActions = async () => {
28013
- if (pendingActions.shouldSetUpCi) await performCiSetup(rootDirectory);
28014
- if (pendingActions.didQuit) return;
28015
- if (pendingActions.handoffRequest) await performTuiHandoff(pendingActions.handoffRequest, rootDirectory);
28016
- };
28017
- return {
28018
- store,
28019
- pendingActions,
28020
- mountRenderer,
28021
- executePendingActions
28022
- };
28023
- };
28024
- const runMountedScan = async (rootDirectory, presentation, blockingLevel, executeScan) => {
28025
- const { store, pendingActions, mountRenderer, executePendingActions } = await mountScanApp(rootDirectory, presentation.shouldRecommendCi, presentation.initialProgress);
28026
- let mountedRenderer = mountRenderer("scan");
28027
- recordCount(METRIC.tuiScanInlineShown);
28028
- const context = {
28029
- store,
28030
- ...presentation
28031
- };
28032
- try {
28033
- const completedScan = await executeScan(context);
28034
- mountedRenderer.dispose();
28035
- mountedRenderer = mountRenderer("report");
28036
- await mountedRenderer.instance.waitUntilExit();
28037
- mountedRenderer.dispose();
28038
- if (presentation.outputDirectory !== void 0 || presentation.verbose) await runPromise(printDiagnosticsDump([...completedScan.diagnostics], presentation.outputDirectory, presentation.verbose));
28039
- if (!pendingActions.didQuit) await printExitFooter({
28040
- diagnostics: completedScan.diagnostics,
28041
- scoreResult: completedScan.scoreResult,
28042
- projectName: completedScan.projectName,
28043
- scannedFileCount: completedScan.scannedFileCount,
28044
- elapsedMilliseconds: completedScan.elapsedMilliseconds,
28045
- isOffline: context.isOffline,
28046
- lintFailureReason: resolveLintFailureReason(completedScan.scans.map(({ result }) => result))
28047
- });
28048
- await executePendingActions();
28049
- return { shouldFail: shouldFailScanGate({
28050
- scans: completedScan.scans,
28051
- blockingLevel,
28052
- diagnosticsAreGateExempt: completedScan.diagnosticsAreGateExempt
28053
- }) };
28054
- } catch (error) {
28055
- mountedRenderer.dispose();
28056
- throw error;
28057
- }
28058
- };
28059
- const runSingleProjectScan = async (rootScanTarget, projectDirectory, input, scopePlan, blockingLevel, inspectProject) => {
28060
- const projectScan = await resolveProjectScan(rootScanTarget, projectDirectory);
28061
- const isSupplyChainEnabled = input.options?.supplyChain ?? projectScan.config?.supplyChain?.enabled ?? true;
28062
- const scopeOptions = resolveProjectTuiScanScope({
28063
- plan: scopePlan,
28064
- projectDirectory: projectScan.directory,
28065
- rootDirectory: rootScanTarget.resolvedDirectory,
28066
- supplyChainEnabled: isSupplyChainEnabled
28067
- });
28068
- if (scopeOptions === null) {
28069
- process.stdout.write("No changed source files in the selected project.\n");
28070
- return { shouldFail: false };
28071
25659
  }
28072
- const presentation = resolveScanPresentation(input, [projectScan]);
28073
- return runMountedScan(projectScan.directory, presentation, blockingLevel, async (context) => {
28074
- const result = await inspectProject(projectScan.directory, {
28075
- ...resolveTuiInspectOptions(input, projectScan.config),
28076
- ...scopeOptions,
28077
- isCi: isCiEnvironment(),
28078
- configOverride: projectScan.config,
28079
- configSourceDirectory: projectScan.configSourceDirectory ?? void 0,
28080
- uiLayers: {
28081
- reporter: reporterLayerForStore(context.store),
28082
- progress: progressLayerForStore(context.store)
25660
+ exports.Fragment = REACT_FRAGMENT_TYPE;
25661
+ exports.jsx = jsxProd;
25662
+ exports.jsxs = jsxProd;
25663
+ }));
25664
+ //#endregion
25665
+ //#region ../../node_modules/.pnpm/react@19.2.5/node_modules/react/cjs/react-jsx-runtime.development.js
25666
+ /**
25667
+ * @license React
25668
+ * react-jsx-runtime.development.js
25669
+ *
25670
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
25671
+ *
25672
+ * This source code is licensed under the MIT license found in the
25673
+ * LICENSE file in the root directory of this source tree.
25674
+ */
25675
+ var require_react_jsx_runtime_development = /* @__PURE__ */ __commonJSMin(((exports) => {
25676
+ "production" !== process.env.NODE_ENV && (function() {
25677
+ function getComponentNameFromType(type) {
25678
+ if (null == type) return null;
25679
+ if ("function" === typeof type) return type.$$typeof === REACT_CLIENT_REFERENCE ? null : type.displayName || type.name || null;
25680
+ if ("string" === typeof type) return type;
25681
+ switch (type) {
25682
+ case REACT_FRAGMENT_TYPE: return "Fragment";
25683
+ case REACT_PROFILER_TYPE: return "Profiler";
25684
+ case REACT_STRICT_MODE_TYPE: return "StrictMode";
25685
+ case REACT_SUSPENSE_TYPE: return "Suspense";
25686
+ case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList";
25687
+ case REACT_ACTIVITY_TYPE: return "Activity";
28083
25688
  }
28084
- });
28085
- const reportSelection = selectReportDiagnostics({
28086
- scan: {
28087
- result,
28088
- config: projectScan.config
28089
- },
28090
- categoryFilters: input.options?.categoryFilters,
28091
- surface: input.options?.outputSurface
28092
- });
28093
- const scoreDiagnostics = filterScansForSurface([{
28094
- result,
28095
- config: projectScan.config
28096
- }], "score");
28097
- const projectedScore = result.score ? await computeProjectedScore([...reportSelection.diagnostics], scoreDiagnostics, result.score) : null;
28098
- context.store.setReport(toScanReport({
28099
- result,
28100
- diagnostics: reportSelection.diagnostics,
28101
- rootDirectory: projectScan.directory,
28102
- projectedScore,
28103
- isOffline: context.isOffline,
28104
- noScoreMessage: buildNoScoreMessage({
28105
- isScoreDisabled: input.options?.noScore === true || projectScan.config?.noScore === true,
28106
- isAnalysisIncomplete: hasIncompleteScoreAnalysis(result.skippedChecks),
28107
- disabledMessage: input.options?.scoreDisabledMessage
28108
- }),
28109
- emptyStateMessage: resolveEmptyStateMessage(input, reportSelection.demotedDiagnosticCount)
28110
- }));
28111
- return {
28112
- scans: [{
28113
- result,
28114
- config: projectScan.config
28115
- }],
28116
- diagnostics: reportSelection.diagnostics,
28117
- diagnosticsAreGateExempt: scopePlan.baselineIntended && result.baselineDelta === void 0,
28118
- scoreResult: result.score,
28119
- projectName: result.project.projectName,
28120
- scannedFileCount: result.scannedFileCount ?? 0,
28121
- elapsedMilliseconds: result.elapsedMilliseconds
28122
- };
28123
- });
28124
- };
28125
- const runMultiProjectScan = async (rootScanTarget, directories, input, scopePlan, blockingLevel, inspectProject) => {
28126
- const feedbackStartTime = performance$1.now();
28127
- const rootDirectory = rootScanTarget.resolvedDirectory;
28128
- const discoveredProjectScans = deduplicateProjectScans(await mapWithConcurrency([...directories], 4, (projectDirectory) => resolveProjectScan(rootScanTarget, projectDirectory)));
28129
- const projectScans = discoveredProjectScans.flatMap((projectScan) => {
28130
- const isSupplyChainEnabled = input.options?.supplyChain ?? projectScan.config?.supplyChain?.enabled ?? true;
28131
- const scopeOptions = resolveProjectTuiScanScope({
28132
- plan: scopePlan,
28133
- projectDirectory: projectScan.directory,
28134
- rootDirectory,
28135
- supplyChainEnabled: isSupplyChainEnabled
28136
- });
28137
- return scopeOptions === null ? [] : [{
28138
- projectScan,
28139
- scopeOptions
28140
- }];
28141
- });
28142
- if (projectScans.length === 0) {
28143
- process.stdout.write("No changed source files in the selected projects.\n");
28144
- return { shouldFail: false };
28145
- }
28146
- const projectCount = projectScans.length;
28147
- const rootProjectScan = discoveredProjectScans.find((projectScan) => path.resolve(projectScan.directory) === path.resolve(rootDirectory));
28148
- const workspaceDeadCodeOwner = resolveWorkspaceDeadCodeOwner({
28149
- rootDirectory,
28150
- projectDirectories: discoveredProjectScans.map((projectScan) => projectScan.directory),
28151
- isRootDeadCodeEnabled: input.options?.deadCode ?? rootProjectScan?.config?.deadCode ?? true
28152
- });
28153
- if (workspaceDeadCodeOwner !== null) recordCount(METRIC.scanWorkspaceDeadCodeShared, 1, { projectCount: discoveredProjectScans.length });
28154
- return runMountedScan(rootDirectory, resolveScanPresentation(input, projectScans.map(({ projectScan }) => projectScan)), blockingLevel, async (context) => {
28155
- const startTime = performance$1.now();
28156
- let finishedCount = 0;
28157
- recordDistribution(METRIC.scanFeedbackDelay, performance$1.now() - feedbackStartTime, {
28158
- unit: "millisecond",
28159
- attributes: {
28160
- surface: "tui",
28161
- projectCount
25689
+ if ("object" === typeof type) switch ("number" === typeof type.tag && console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."), type.$$typeof) {
25690
+ case REACT_PORTAL_TYPE: return "Portal";
25691
+ case REACT_CONTEXT_TYPE: return type.displayName || "Context";
25692
+ case REACT_CONSUMER_TYPE: return (type._context.displayName || "Context") + ".Consumer";
25693
+ case REACT_FORWARD_REF_TYPE:
25694
+ var innerType = type.render;
25695
+ type = type.displayName;
25696
+ type || (type = innerType.displayName || innerType.name || "", type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef");
25697
+ return type;
25698
+ case REACT_MEMO_TYPE: return innerType = type.displayName || null, null !== innerType ? innerType : getComponentNameFromType(type.type) || "Memo";
25699
+ case REACT_LAZY_TYPE:
25700
+ innerType = type._payload;
25701
+ type = type._init;
25702
+ try {
25703
+ return getComponentNameFromType(type(innerType));
25704
+ } catch (x) {}
28162
25705
  }
28163
- });
28164
- context.store.setProgress(`Scanning ${projectCount} projects…`);
28165
- await yieldToEventLoop();
28166
- const precomputedSourceFileCounts = scopePlan.scope === "full" ? await collectProjectSourceFileCounts(rootDirectory, projectScans.map(({ projectScan }) => projectScan.directory)) : null;
28167
- const { completedScans, skippedScans } = partitionProjectScanOutcomes(await mapWithConcurrency(projectScans, 4, async ({ projectScan, scopeOptions }) => {
28168
- if (input.options?.deadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(input.options.deadlineEpochMs) === 0) {
28169
- finishedCount += 1;
28170
- context.store.setProgress(`Scanning ${projectCount} projects… (${finishedCount}/${projectCount})`);
28171
- return {
28172
- status: "skipped",
28173
- value: {
28174
- directory: projectScan.directory,
28175
- reason: "max-duration"
28176
- }
28177
- };
25706
+ return null;
25707
+ }
25708
+ function testStringCoercion(value) {
25709
+ return "" + value;
25710
+ }
25711
+ function checkKeyStringCoercion(value) {
25712
+ try {
25713
+ testStringCoercion(value);
25714
+ var JSCompiler_inline_result = !1;
25715
+ } catch (e) {
25716
+ JSCompiler_inline_result = !0;
28178
25717
  }
28179
- const projectLabel = path.relative(rootDirectory, projectScan.directory) || path.basename(rootDirectory);
28180
- const formatProjectProgress = (displayText) => `Scanning ${projectCount} projects… (${finishedCount}/${projectCount}) · ${projectLabel}: ${displayText}`;
28181
- const inspectOptions = resolveTuiInspectOptions(input, projectScan.config);
28182
- const ownsWorkspaceDeadCode = projectScan.directory === workspaceDeadCodeOwner;
28183
- const result = await inspectProject(projectScan.directory, {
28184
- ...inspectOptions,
28185
- ...scopeOptions,
28186
- deadCode: workspaceDeadCodeOwner === null ? inspectOptions.deadCode : ownsWorkspaceDeadCode,
28187
- isCi: isCiEnvironment(),
28188
- configOverride: projectScan.config,
28189
- configSourceDirectory: projectScan.configSourceDirectory ?? void 0,
28190
- precomputedSourceFileCount: precomputedSourceFileCounts?.get(projectScan.directory),
28191
- uiLayers: {
28192
- reporter: Reporter.layerNoop,
28193
- progress: progressLayerForStore(context.store, {
28194
- transformText: formatProjectProgress,
28195
- shouldClearOnStop: false
28196
- })
28197
- },
28198
- concurrentScan: true,
28199
- excludedProjectDirectories: discoveredProjectScans.filter((candidateProjectScan) => isPathInsideDirectory(candidateProjectScan.directory, projectScan.directory)).map((candidateProjectScan) => candidateProjectScan.directory),
28200
- retainExcludedProjectDeadCodeDiagnostics: ownsWorkspaceDeadCode
25718
+ if (JSCompiler_inline_result) {
25719
+ JSCompiler_inline_result = console;
25720
+ var JSCompiler_temp_const = JSCompiler_inline_result.error;
25721
+ var JSCompiler_inline_result$jscomp$0 = "function" === typeof Symbol && Symbol.toStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object";
25722
+ JSCompiler_temp_const.call(JSCompiler_inline_result, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", JSCompiler_inline_result$jscomp$0);
25723
+ return testStringCoercion(value);
25724
+ }
25725
+ }
25726
+ function getTaskName(type) {
25727
+ if (type === REACT_FRAGMENT_TYPE) return "<>";
25728
+ if ("object" === typeof type && null !== type && type.$$typeof === REACT_LAZY_TYPE) return "<...>";
25729
+ try {
25730
+ var name = getComponentNameFromType(type);
25731
+ return name ? "<" + name + ">" : "<...>";
25732
+ } catch (x) {
25733
+ return "<...>";
25734
+ }
25735
+ }
25736
+ function getOwner() {
25737
+ var dispatcher = ReactSharedInternals.A;
25738
+ return null === dispatcher ? null : dispatcher.getOwner();
25739
+ }
25740
+ function UnknownOwner() {
25741
+ return Error("react-stack-top-frame");
25742
+ }
25743
+ function hasValidKey(config) {
25744
+ if (hasOwnProperty.call(config, "key")) {
25745
+ var getter = Object.getOwnPropertyDescriptor(config, "key").get;
25746
+ if (getter && getter.isReactWarning) return !1;
25747
+ }
25748
+ return void 0 !== config.key;
25749
+ }
25750
+ function defineKeyPropWarningGetter(props, displayName) {
25751
+ function warnAboutAccessingKey() {
25752
+ specialPropKeyWarningShown || (specialPropKeyWarningShown = !0, console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", displayName));
25753
+ }
25754
+ warnAboutAccessingKey.isReactWarning = !0;
25755
+ Object.defineProperty(props, "key", {
25756
+ get: warnAboutAccessingKey,
25757
+ configurable: !0
28201
25758
  });
28202
- finishedCount += 1;
28203
- context.store.setProgress(`Scanning ${projectCount} projects… (${finishedCount}/${projectCount})`);
28204
- await yieldToEventLoop();
28205
- return {
28206
- status: "completed",
28207
- value: {
28208
- directory: projectScan.directory,
28209
- result,
28210
- config: projectScan.config
28211
- }
25759
+ }
25760
+ function elementRefGetterWithDeprecationWarning() {
25761
+ var componentName = getComponentNameFromType(this.type);
25762
+ didWarnAboutElementRef[componentName] || (didWarnAboutElementRef[componentName] = !0, console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."));
25763
+ componentName = this.props.ref;
25764
+ return void 0 !== componentName ? componentName : null;
25765
+ }
25766
+ function ReactElement(type, key, props, owner, debugStack, debugTask) {
25767
+ var refProp = props.ref;
25768
+ type = {
25769
+ $$typeof: REACT_ELEMENT_TYPE,
25770
+ type,
25771
+ key,
25772
+ props,
25773
+ _owner: owner
28212
25774
  };
28213
- }));
28214
- const results = await retryMissingProjectScores(completedScans.map((completedScan) => ({
28215
- ...completedScan,
28216
- isScoreDisabled: input.options?.noScore ?? completedScan.config?.noScore ?? false
28217
- })));
28218
- const skippedProjects = skippedScans.sort((left, right) => left.directory.localeCompare(right.directory));
28219
- if (skippedProjects.length > 0) recordCount(METRIC.scanProjectSkipped, skippedProjects.length, { reason: "max-duration" });
28220
- const projectEntries = results.map(({ directory, result, config }) => {
28221
- const reportSelection = selectReportDiagnostics({
28222
- scan: {
28223
- result,
28224
- config
28225
- },
28226
- categoryFilters: input.options?.categoryFilters,
28227
- surface: input.options?.outputSurface
25775
+ null !== (void 0 !== refProp ? refProp : null) ? Object.defineProperty(type, "ref", {
25776
+ enumerable: !1,
25777
+ get: elementRefGetterWithDeprecationWarning
25778
+ }) : Object.defineProperty(type, "ref", {
25779
+ enumerable: !1,
25780
+ value: null
28228
25781
  });
28229
- return {
28230
- report: toScanReport({
28231
- result,
28232
- diagnostics: reportSelection.diagnostics,
28233
- rootDirectory: directory,
28234
- projectedScore: null,
28235
- isOffline: context.isOffline,
28236
- noScoreMessage: buildNoScoreMessage({
28237
- isScoreDisabled: input.options?.noScore === true || config?.noScore === true,
28238
- isAnalysisIncomplete: hasIncompleteScoreAnalysis(result.skippedChecks),
28239
- disabledMessage: input.options?.scoreDisabledMessage
28240
- }),
28241
- emptyStateMessage: resolveEmptyStateMessage(input, reportSelection.demotedDiagnosticCount)
28242
- }),
28243
- score: result.score,
28244
- scoreDiagnostics: filterScansForSurface([{
28245
- result,
28246
- config
28247
- }], "score"),
28248
- demotedDiagnosticCount: reportSelection.demotedDiagnosticCount
28249
- };
28250
- });
28251
- const projects = projectEntries.map(({ report }) => report);
28252
- const combinedDiagnostics = projects.flatMap((project) => qualifyDiagnosticPaths(project.diagnostics, rootDirectory, project.rootDirectory));
28253
- const lowestScoredReport = findLowestScoredReport(projectEntries);
28254
- const projectedScore = lowestScoredReport ? await computeProjectedScore(combinedDiagnostics, [...lowestScoredReport.scoreDiagnostics], lowestScoredReport.score) : null;
28255
- const scannedFileCount = countUniqueScannedFiles(results.map(({ result }) => result));
28256
- const elapsedMilliseconds = performance$1.now() - startTime;
28257
- const lintFailureReason = resolveLintFailureReason(results.map(({ result }) => result));
28258
- const summary = {
28259
- projects,
28260
- skippedProjects,
28261
- aggregateScore: lowestScoredReport?.score ?? null,
28262
- projectedScore,
28263
- combinedDiagnostics,
28264
- scannedFileCount,
28265
- elapsedMilliseconds,
28266
- projectName: path.basename(rootDirectory),
28267
- rootDirectory,
28268
- isOffline: context.isOffline,
28269
- noScoreMessage: buildNoScoreMessage({
28270
- isScoreDisabled: input.options?.noScore === true || results.some(({ config }) => config?.noScore === true),
28271
- isAnalysisIncomplete: results.some(({ result }) => hasIncompleteScoreAnalysis(result.skippedChecks)),
28272
- disabledMessage: input.options?.scoreDisabledMessage
28273
- }),
28274
- emptyStateMessage: resolveEmptyStateMessage(input, projectEntries.reduce((total, projectEntry) => total + projectEntry.demotedDiagnosticCount, 0)),
28275
- ...lintFailureReason ? { lintFailureReason } : {}
25782
+ type._store = {};
25783
+ Object.defineProperty(type._store, "validated", {
25784
+ configurable: !1,
25785
+ enumerable: !1,
25786
+ writable: !0,
25787
+ value: 0
25788
+ });
25789
+ Object.defineProperty(type, "_debugInfo", {
25790
+ configurable: !1,
25791
+ enumerable: !1,
25792
+ writable: !0,
25793
+ value: null
25794
+ });
25795
+ Object.defineProperty(type, "_debugStack", {
25796
+ configurable: !1,
25797
+ enumerable: !1,
25798
+ writable: !0,
25799
+ value: debugStack
25800
+ });
25801
+ Object.defineProperty(type, "_debugTask", {
25802
+ configurable: !1,
25803
+ enumerable: !1,
25804
+ writable: !0,
25805
+ value: debugTask
25806
+ });
25807
+ Object.freeze && (Object.freeze(type.props), Object.freeze(type));
25808
+ return type;
25809
+ }
25810
+ function jsxDEVImpl(type, config, maybeKey, isStaticChildren, debugStack, debugTask) {
25811
+ var children = config.children;
25812
+ if (void 0 !== children) if (isStaticChildren) if (isArrayImpl(children)) {
25813
+ for (isStaticChildren = 0; isStaticChildren < children.length; isStaticChildren++) validateChildKeys(children[isStaticChildren]);
25814
+ Object.freeze && Object.freeze(children);
25815
+ } else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");
25816
+ else validateChildKeys(children);
25817
+ if (hasOwnProperty.call(config, "key")) {
25818
+ children = getComponentNameFromType(type);
25819
+ var keys = Object.keys(config).filter(function(k) {
25820
+ return "key" !== k;
25821
+ });
25822
+ isStaticChildren = 0 < keys.length ? "{key: someKey, " + keys.join(": ..., ") + ": ...}" : "{key: someKey}";
25823
+ didWarnAboutKeySpread[children + isStaticChildren] || (keys = 0 < keys.length ? "{" + keys.join(": ..., ") + ": ...}" : "{}", console.error("A props object containing a \"key\" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />", isStaticChildren, children, keys, children), didWarnAboutKeySpread[children + isStaticChildren] = !0);
25824
+ }
25825
+ children = null;
25826
+ void 0 !== maybeKey && (checkKeyStringCoercion(maybeKey), children = "" + maybeKey);
25827
+ hasValidKey(config) && (checkKeyStringCoercion(config.key), children = "" + config.key);
25828
+ if ("key" in config) {
25829
+ maybeKey = {};
25830
+ for (var propName in config) "key" !== propName && (maybeKey[propName] = config[propName]);
25831
+ } else maybeKey = config;
25832
+ children && defineKeyPropWarningGetter(maybeKey, "function" === typeof type ? type.displayName || type.name || "Unknown" : type);
25833
+ return ReactElement(type, children, maybeKey, getOwner(), debugStack, debugTask);
25834
+ }
25835
+ function validateChildKeys(node) {
25836
+ isValidElement(node) ? node._store && (node._store.validated = 1) : "object" === typeof node && null !== node && node.$$typeof === REACT_LAZY_TYPE && ("fulfilled" === node._payload.status ? isValidElement(node._payload.value) && node._payload.value._store && (node._payload.value._store.validated = 1) : node._store && (node._store.validated = 1));
25837
+ }
25838
+ function isValidElement(object) {
25839
+ return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
25840
+ }
25841
+ var React = require_react(), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
25842
+ return null;
28276
25843
  };
28277
- context.store.setSummary(summary);
28278
- return {
28279
- scans: results,
28280
- diagnostics: combinedDiagnostics,
28281
- diagnosticsAreGateExempt: scopePlan.baselineIntended && (skippedProjects.length > 0 || results.length === 0 || results.some(({ result }) => result.baselineDelta === void 0)),
28282
- scoreResult: summary.aggregateScore,
28283
- projectName: summary.projectName,
28284
- scannedFileCount,
28285
- elapsedMilliseconds
25844
+ React = { react_stack_bottom_frame: function(callStackForError) {
25845
+ return callStackForError();
25846
+ } };
25847
+ var specialPropKeyWarningShown;
25848
+ var didWarnAboutElementRef = {};
25849
+ var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(React, UnknownOwner)();
25850
+ var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
25851
+ var didWarnAboutKeySpread = {};
25852
+ exports.Fragment = REACT_FRAGMENT_TYPE;
25853
+ exports.jsx = function(type, config, maybeKey) {
25854
+ var trackActualOwner = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
25855
+ return jsxDEVImpl(type, config, maybeKey, !1, trackActualOwner ? Error("react-stack-top-frame") : unknownOwnerDebugStack, trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask);
28286
25856
  };
28287
- });
28288
- };
28289
- const runScanApp = async (input) => {
28290
- const scanTarget = input.scanTarget ?? await resolveScanTarget(input.directory, { allowAmbiguous: true });
28291
- const rootDirectory = scanTarget.resolvedDirectory;
28292
- const scopePlan = await resolveTuiScanScope({
28293
- directory: rootDirectory,
28294
- flags: input.flags ?? {},
28295
- userConfig: scanTarget.userConfig
28296
- });
28297
- const deadlineEpochMs = input.options?.deadlineEpochMs ?? (input.options?.maxDurationMs != null ? Date.now() + input.options.maxDurationMs : void 0);
28298
- const resolvedInput = {
28299
- ...input,
28300
- options: {
28301
- ...input.options,
28302
- deadlineEpochMs
28303
- },
28304
- configProjects: input.configProjects ?? scanTarget.userConfig?.projects,
28305
- share: input.share ?? scanTarget.userConfig?.share ?? true
28306
- };
28307
- const selectedDirectories = await resolveSelectedDirectories(rootDirectory, resolvedInput);
28308
- const inspectProject = createInvocationInspect(input.options?.concurrency);
28309
- const blockingLevel = resolveBlockingLevel({ blocking: resolvedInput.blocking }, scanTarget.userConfig);
28310
- if (selectedDirectories.length === 0) return { shouldFail: false };
28311
- if (selectedDirectories.length === 1) return runSingleProjectScan(scanTarget, selectedDirectories[0], resolvedInput, scopePlan, blockingLevel, inspectProject);
28312
- return runMultiProjectScan(scanTarget, selectedDirectories, resolvedInput, scopePlan, blockingLevel, inspectProject);
28313
- };
25857
+ exports.jsxs = function(type, config, maybeKey) {
25858
+ var trackActualOwner = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
25859
+ return jsxDEVImpl(type, config, maybeKey, !0, trackActualOwner ? Error("react-stack-top-frame") : unknownOwnerDebugStack, trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask);
25860
+ };
25861
+ })();
25862
+ }));
25863
+ //#endregion
25864
+ //#region ../../node_modules/.pnpm/react@19.2.5/node_modules/react/jsx-runtime.js
25865
+ var require_jsx_runtime = /* @__PURE__ */ __commonJSMin(((exports, module) => {
25866
+ if (process.env.NODE_ENV === "production") module.exports = require_react_jsx_runtime_production();
25867
+ else module.exports = require_react_jsx_runtime_development();
25868
+ }));
28314
25869
  //#endregion
28315
- export { runScanApp };
25870
+ export { useExitOnCtrlC as a, Spinner as c, useInput as d, Transform as f, Box as h, import_react as i, useStdout as l, Text as m, registerMountedTuiRenderer as n, terminalSymbols as o, render as p, useStdoutDimensions as r, isPrintableInput as s, require_jsx_runtime as t, useApp as u };
28316
25871
 
28317
- //# sourceMappingURL=run-scan-app-BGzlyiIB.js.map
28318
- //# debugId=79ca2870-c5c5-5bc1-92cd-ec761fd7f27f
25872
+ //# sourceMappingURL=jsx-runtime-pWsmwZGj.js.map
25873
+ //# debugId=a329e542-01f9-5ef2-a316-8873ce41d83a