react-doctor 0.9.12-dev.ffc2d14 → 0.9.13-dev.fd23edc

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 (47) hide show
  1. package/README.md +33 -0
  2. package/dist/active-run-trace-dlIZeEvb.js +18 -0
  3. package/dist/active-scan-abort-registry-DwG6tSPy.js +28 -0
  4. package/dist/{build-section-divider-BuOtLrzK.js → build-section-divider-CUtO-gXD.js} +8 -22
  5. package/dist/{ci-DVVsf25h.js → ci-DjilJaw4.js} +12 -11
  6. package/dist/cli.js +116 -35
  7. package/dist/{design-Y1pcA2uj.js → design-CXLKbARh.js} +4 -4
  8. package/dist/{devtools-D8NTVj81.js → devtools-CC2PAZ85.js} +3 -3
  9. package/dist/{exit-gracefully-DnXGONjj.js → exit-gracefully-DTLgxZZ5.js} +15 -9
  10. package/dist/get-east-asian-width-Bv2TD3Xj.js +444 -0
  11. package/dist/{report-error-MGKyeIns.js → handle-error-BqaqFvmc.js} +18 -68
  12. package/dist/index.d.ts +32 -0
  13. package/dist/index.js +585 -286
  14. package/dist/{inspect-g3_lzs3l.js → inspect-BIfnzKGq.js} +38 -28
  15. package/dist/{install-doctor-script-DmEWQpVJ.js → install-doctor-script-B1U08lUD.js} +7 -449
  16. package/dist/{install-github-workflow-Dx6Pl9Wl.js → install-github-workflow-CkOl0wCn.js} +10 -6
  17. package/dist/{install-02Lq6wKC.js → install-nhJ65X-y.js} +9 -8
  18. package/dist/{install-react-doctor-CMCXgenA.js → install-react-doctor-Dm35Egex.js} +8 -8
  19. package/dist/{run-scan-app-CDDu7P32.js → jsx-runtime-C1t3eR6p.js} +280 -2774
  20. package/dist/path-format-DnHpmJwG.js +9 -0
  21. package/dist/{print-branded-header-kbvWYuGv.js → print-branded-header-qOJiGkuW.js} +4 -4
  22. package/dist/project-analysis-worker.js +54 -53
  23. package/dist/prompt-runtime-scan-url-m88LMtMP.js +240 -0
  24. package/dist/{read-object-file-Cwhr9OIi.js → read-object-file-Cv41FpZo.js} +4 -4
  25. package/dist/{record-metric-CFfsgcVs.js → record-metric-u8youmM2.js} +548 -235
  26. package/dist/report-error-CkFgxJTQ.js +64 -0
  27. package/dist/{report-workflow-result-DGg9xopH.js → report-workflow-result-Wh1SQuOu.js} +5 -5
  28. package/dist/{resolve-scope-CXS-5jLR.js → resolve-scope-CHCpJtks.js} +8 -10
  29. package/dist/{rules-CThlosPx.js → rules-C30QFptP.js} +6 -6
  30. package/dist/run-scan-app-yTBDucJ3.js +2511 -0
  31. package/dist/runtime-scan/browser-probe.iife.js +855 -0
  32. package/dist/runtime-scan-VH25Yf8H.js +770 -0
  33. package/dist/sanitize-runtime-url-crVHbQlW.js +76 -0
  34. package/dist/scan-CNSRWEtJ.js +47 -0
  35. package/dist/{should-fail-scan-gate-C0Bo5Gqy.js → should-fail-scan-gate-Cw6KeoRT.js} +20 -112
  36. package/dist/{should-skip-prompts-BqrtVX4G.js → should-skip-prompts-B5zkkkKR.js} +4 -4
  37. package/dist/should-use-tui-S9255AG_.js +25 -0
  38. package/dist/skills/improve-threejs/SKILL.md +102 -0
  39. package/dist/skills/performance/SKILL.md +113 -0
  40. package/dist/skills/react-doctor/SKILL.md +6 -0
  41. package/dist/{unref-stdin-BxyvqsOy.js → telemetry-runtime-B2rpGWMl.js} +55 -25
  42. package/dist/unref-stdin-SK3WfwxS.js +12 -0
  43. package/dist/{version-S-8vvWFi.js → version-KQbGQSGN.js} +4 -4
  44. package/dist/{why-DXfx0oL9.js → why-B-l2qTCV.js} +4 -4
  45. package/dist/with-run-span-Dk1M8cnH.js +110 -0
  46. package/package.json +9 -6
  47. package/dist/scan-4I1mvxBO.js +0 -53
@@ -0,0 +1,9 @@
1
+ //#region src/cli/utils/path-format.ts
2
+
3
+ !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]="0330366c-931b-5aad-9410-de708cd22f46")}catch(e){}}();
4
+ const toForwardSlashes = (filePath) => filePath.replaceAll("\\", "/");
5
+ //#endregion
6
+ export { toForwardSlashes as t };
7
+
8
+ //# sourceMappingURL=path-format-DnHpmJwG.js.map
9
+ //# debugId=0330366c-931b-5aad-9410-de708cd22f46
@@ -1,6 +1,6 @@
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]="402115ce-fe71-5fe0-af57-10cbf55e8242")}catch(e){}}();
3
- import { Gt as highlighter, g as VERSION, kn as gen, wn as log } from "./record-metric-CFfsgcVs.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]="2720bc27-fcb2-5332-865f-659129ff94dd")}catch(e){}}();
3
+ import { An as gen, Kt as highlighter, Tn as log, _ as VERSION } from "./record-metric-u8youmM2.js";
4
4
  //#region src/cli/utils/print-branded-header.ts
5
5
  /**
6
6
  * Single branded line every command prints first when not in JSON
@@ -18,5 +18,5 @@ const printBrandedHeader = gen(function* () {
18
18
  //#endregion
19
19
  export { printBrandedHeader as t };
20
20
 
21
- //# sourceMappingURL=print-branded-header-kbvWYuGv.js.map
22
- //# debugId=402115ce-fe71-5fe0-af57-10cbf55e8242
21
+ //# sourceMappingURL=print-branded-header-qOJiGkuW.js.map
22
+ //# debugId=2720bc27-fcb2-5332-865f-659129ff94dd
@@ -1,5 +1,5 @@
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]="ea6b7ff6-0d96-50d7-b114-197a98204476")}catch(e){}}();
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]="98b361a0-3811-59d7-bcea-c6d79bbebdbd")}catch(e){}}();
3
3
  import { i as __toESM, n as __exportAll, r as __require, t as __commonJSMin } from "./chunk-ChKA3wi6.js";
4
4
  import { n as require_picomatch$2, t as require_semver } from "./semver-DFtnEmN-.js";
5
5
  import { builtinModules } from "node:module";
@@ -9,12 +9,12 @@ import path, { basename, dirname, extname, isAbsolute, join, parse, posix, relat
9
9
  import * as fs$1 from "node:fs";
10
10
  import { existsSync, readFileSync, readdirSync, realpathSync, statSync } from "node:fs";
11
11
  import ts from "typescript";
12
+ import { parseSync } from "oxc-parser";
12
13
  import { ResolverFactory } from "oxc-resolver";
13
14
  import { devNull } from "node:os";
14
15
  import { parseJSONC, parseTOML, parseYAML } from "confbox";
15
16
  import { readFile } from "node:fs/promises";
16
17
  import { parse as parse$1 } from "@astrojs/compiler/sync";
17
- import { parseSync } from "oxc-parser";
18
18
  //#region ../core/src/project-analysis/constants.ts
19
19
  const DEFAULT_EXTENSIONS = [
20
20
  ".ts",
@@ -38057,6 +38057,13 @@ const discoverMobileEntryPoints = (directory) => {
38057
38057
  }
38058
38058
  };
38059
38059
  //#endregion
38060
+ //#region ../core/src/utils/unwrap-typescript-expression.ts
38061
+ const unwrapTypescriptExpression = (expression) => {
38062
+ let currentExpression = expression;
38063
+ while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
38064
+ return currentExpression;
38065
+ };
38066
+ //#endregion
38060
38067
  //#region ../core/src/project-analysis/collect/expo-config-plugin-entries.ts
38061
38068
  const EXPO_CONFIG_FILE_GLOBS = ["app.config.{ts,mts,cts,js,mjs,cjs}", "app.json"];
38062
38069
  const NESTED_EXPO_CONFIG_FILE_GLOBS = [
@@ -38102,11 +38109,6 @@ const addExpoPluginEntry = (entries, packageNamePlugins, rootDirectory, configDi
38102
38109
  const getPropertyName$4 = (name) => {
38103
38110
  if (ts.isIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name)) return name.text;
38104
38111
  };
38105
- const unwrapExpression = (expression) => {
38106
- let currentExpression = expression;
38107
- while (ts.isParenthesizedExpression(currentExpression)) currentExpression = currentExpression.expression;
38108
- return currentExpression;
38109
- };
38110
38112
  const collectExpoPluginPathsFromArray = (array, entries, packageNamePlugins, rootDirectory, configDirectory) => {
38111
38113
  for (const element of array.elements) {
38112
38114
  if (ts.isStringLiteral(element) || ts.isNoSubstitutionTemplateLiteral(element)) {
@@ -38129,14 +38131,14 @@ const collectExpoPluginPathsFromConfigObject = (objectLiteral, entries, packageN
38129
38131
  };
38130
38132
  const collectReturnedExpoConfigPluginPaths = (body, entries, packageNamePlugins, rootDirectory, configDirectory) => {
38131
38133
  if (!ts.isBlock(body)) {
38132
- const expression = unwrapExpression(body);
38134
+ const expression = unwrapTypescriptExpression(body);
38133
38135
  if (ts.isObjectLiteralExpression(expression)) collectExpoPluginPathsFromConfigObject(expression, entries, packageNamePlugins, rootDirectory, configDirectory);
38134
38136
  return;
38135
38137
  }
38136
38138
  const visit = (node) => {
38137
38139
  if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node)) return;
38138
38140
  if (ts.isReturnStatement(node) && node.expression) {
38139
- const expression = unwrapExpression(node.expression);
38141
+ const expression = unwrapTypescriptExpression(node.expression);
38140
38142
  if (ts.isObjectLiteralExpression(expression)) collectExpoPluginPathsFromConfigObject(expression, entries, packageNamePlugins, rootDirectory, configDirectory);
38141
38143
  return;
38142
38144
  }
@@ -38145,7 +38147,7 @@ const collectReturnedExpoConfigPluginPaths = (body, entries, packageNamePlugins,
38145
38147
  visit(body);
38146
38148
  };
38147
38149
  const collectExpoPluginPathsFromConfigExpression = (expression, entries, packageNamePlugins, rootDirectory, configDirectory, bindings, seenIdentifiers = /* @__PURE__ */ new Set()) => {
38148
- const configExpression = unwrapExpression(expression);
38150
+ const configExpression = unwrapTypescriptExpression(expression);
38149
38151
  if (ts.isObjectLiteralExpression(configExpression)) {
38150
38152
  collectExpoPluginPathsFromConfigObject(configExpression, entries, packageNamePlugins, rootDirectory, configDirectory);
38151
38153
  return;
@@ -40999,13 +41001,6 @@ const extractSupabaseFunctionEntries = (rootDirectory) => import_out.default.syn
40999
41001
  onlyFiles: true
41000
41002
  });
41001
41003
  //#endregion
41002
- //#region ../core/src/utils/unwrap-typescript-expression.ts
41003
- const unwrapTypescriptExpression = (expression) => {
41004
- let currentExpression = expression;
41005
- while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
41006
- return currentExpression;
41007
- };
41008
- //#endregion
41009
41004
  //#region ../core/src/project-analysis/utils/is-path-inside-directory-or-equal.ts
41010
41005
  const isPathInsideDirectoryOrEqual = (candidatePath, directoryPath) => {
41011
41006
  const normalizedCandidatePath = posix.normalize(toPosixPath(candidatePath));
@@ -42091,7 +42086,7 @@ const resolveEntries = async (config) => {
42091
42086
  onlyFiles: true
42092
42087
  }));
42093
42088
  }
42094
- if (isEligible && (workspacePackage.isDeclaredWorkspace || !workspaceDiscovery.hasRootLevelWorkspacePatterns)) {
42089
+ if (isEligible) {
42095
42090
  const workspacePackageJsonEntries = await extractPackageJsonEntries(resolve(workspacePackage.directory, "package.json"));
42096
42091
  if (workspacePackageJsonEntries.some((entryPath) => existsSync(entryPath))) {
42097
42092
  workspaceEntries.push(...workspacePackageJsonEntries);
@@ -46087,47 +46082,53 @@ const collectPackageLockPackageMetadata = (searchRoots, resolutionDirectory, dec
46087
46082
  return metadataByPackageName;
46088
46083
  };
46089
46084
  //#endregion
46090
- //#region ../core/src/project-analysis/utils/collect-static-module-package-names.ts
46091
- const collectStaticModulePackageNames = (sourceText) => {
46092
- const parsedModule = parseSync("package-reference.tsx", sourceText, { sourceType: "module" });
46093
- const packageNames = /* @__PURE__ */ new Set();
46094
- const addSpecifier = (specifier) => {
46095
- const packageName = extractPackageName(specifier);
46096
- if (packageName) packageNames.add(packageName);
46097
- };
46098
- const getStaticSpecifier = (value) => {
46099
- if (!isOxcAstNode(value)) return void 0;
46100
- if (typeof value.value === "string") return value.value;
46101
- if (value.type === "TemplateLiteral" && Array.isArray(value.expressions) && value.expressions.length === 0 && Array.isArray(value.quasis) && isOxcAstNode(value.quasis[0]) && value.quasis[0].value && typeof value.quasis[0].value === "object" && "cooked" in value.quasis[0].value && typeof value.quasis[0].value.cooked === "string") return value.quasis[0].value.cooked;
46085
+ //#region ../core/src/project-analysis/utils/collect-static-module-specifiers.ts
46086
+ const getStaticModuleSpecifier = (value) => {
46087
+ if (!isOxcAstNode(value)) return void 0;
46088
+ if (typeof value.value === "string") return value.value;
46089
+ if (value.type === "TemplateLiteral" && Array.isArray(value.expressions) && value.expressions.length === 0 && Array.isArray(value.quasis) && isOxcAstNode(value.quasis[0]) && value.quasis[0].value && typeof value.quasis[0].value === "object" && "cooked" in value.quasis[0].value && typeof value.quasis[0].value.cooked === "string") return value.quasis[0].value.cooked;
46090
+ };
46091
+ const collectStaticModuleSpecifiers = (sourceText, options = {}) => {
46092
+ const { filePath = "module.tsx", includeTypeOnly = true } = options;
46093
+ const parsedModule = parseSync(filePath, sourceText, { sourceType: "unambiguous" });
46094
+ const moduleSpecifiers = /* @__PURE__ */ new Set();
46095
+ const addSpecifier = (value) => {
46096
+ const moduleSpecifier = getStaticModuleSpecifier(value);
46097
+ if (moduleSpecifier) moduleSpecifiers.add(moduleSpecifier);
46102
46098
  };
46103
- for (const staticImport of parsedModule.module.staticImports) addSpecifier(staticImport.moduleRequest.value);
46104
- for (const staticExport of parsedModule.module.staticExports) for (const entry of staticExport.entries) if (entry.moduleRequest) addSpecifier(entry.moduleRequest.value);
46105
- const visitNode = (value, isInTypeScriptModuleBlock = false) => {
46099
+ const visitNode = (value) => {
46106
46100
  if (Array.isArray(value)) {
46107
- for (const child of value) visitNode(child, isInTypeScriptModuleBlock);
46101
+ for (const child of value) visitNode(child);
46108
46102
  return;
46109
46103
  }
46110
46104
  if (!isOxcAstNode(value)) return;
46111
- if (isInTypeScriptModuleBlock && (value.type === "ImportDeclaration" || value.type === "ExportNamedDeclaration" || value.type === "ExportAllDeclaration")) {
46112
- const sourceValue = getStaticSpecifier(value.source);
46113
- if (sourceValue) addSpecifier(sourceValue);
46114
- }
46115
- if (value.type === "ImportExpression" || value.type === "TSImportType") {
46116
- const sourceValue = getStaticSpecifier(value.source);
46117
- if (sourceValue) addSpecifier(sourceValue);
46118
- }
46119
- if (value.type === "TSExternalModuleReference") {
46120
- const expressionValue = getStaticSpecifier(value.expression);
46121
- if (expressionValue) addSpecifier(expressionValue);
46122
- }
46123
- if (value.type === "CallExpression" && isOxcAstNode(value.callee) && value.callee.type === "Identifier" && value.callee.name === "require" && Array.isArray(value.arguments) && value.arguments.length > 0) {
46124
- const argumentValue = getStaticSpecifier(value.arguments[0]);
46125
- if (argumentValue) addSpecifier(argumentValue);
46126
- }
46127
- const childIsInTypeScriptModuleBlock = isInTypeScriptModuleBlock || value.type === "TSModuleBlock";
46128
- for (const child of Object.values(value)) visitNode(child, childIsInTypeScriptModuleBlock);
46105
+ if (value.type === "ImportDeclaration") {
46106
+ const specifiers = Array.isArray(value.specifiers) ? value.specifiers : [];
46107
+ const hasRuntimeSpecifier = specifiers.some((specifier) => !isOxcAstNode(specifier) || specifier.importKind !== "type");
46108
+ if (includeTypeOnly || value.importKind !== "type" && (specifiers.length === 0 || hasRuntimeSpecifier)) addSpecifier(value.source);
46109
+ } else if (value.type === "ExportNamedDeclaration") {
46110
+ const specifiers = Array.isArray(value.specifiers) ? value.specifiers : [];
46111
+ const hasRuntimeSpecifier = specifiers.some((specifier) => !isOxcAstNode(specifier) || specifier.exportKind !== "type");
46112
+ if (includeTypeOnly || value.exportKind !== "type" && (specifiers.length === 0 || hasRuntimeSpecifier)) addSpecifier(value.source);
46113
+ } else if (value.type === "ExportAllDeclaration" || value.type === "ImportExpression") {
46114
+ if (includeTypeOnly || value.exportKind !== "type") addSpecifier(value.source);
46115
+ } else if (value.type === "TSImportType") {
46116
+ if (includeTypeOnly) addSpecifier(value.source);
46117
+ } else if (value.type === "TSExternalModuleReference") addSpecifier(value.expression);
46118
+ else if (value.type === "CallExpression" && isOxcAstNode(value.callee) && value.callee.type === "Identifier" && value.callee.name === "require" && Array.isArray(value.arguments) && value.arguments.length > 0) addSpecifier(value.arguments[0]);
46119
+ for (const child of Object.values(value)) visitNode(child);
46129
46120
  };
46130
46121
  visitNode(parsedModule.program);
46122
+ return moduleSpecifiers;
46123
+ };
46124
+ //#endregion
46125
+ //#region ../core/src/project-analysis/utils/collect-static-module-package-names.ts
46126
+ const collectStaticModulePackageNames = (sourceText) => {
46127
+ const packageNames = /* @__PURE__ */ new Set();
46128
+ for (const specifier of collectStaticModuleSpecifiers(sourceText, { filePath: "package-reference.tsx" })) {
46129
+ const packageName = extractPackageName(specifier);
46130
+ if (packageName) packageNames.add(packageName);
46131
+ }
46131
46132
  return packageNames;
46132
46133
  };
46133
46134
  //#endregion
@@ -51897,4 +51898,4 @@ startProjectAnalysisWorker();
51897
51898
  export {};
51898
51899
 
51899
51900
  //# sourceMappingURL=project-analysis-worker.js.map
51900
- //# debugId=ea6b7ff6-0d96-50d7-b114-197a98204476
51901
+ //# debugId=98b361a0-3811-59d7-bcea-c6d79bbebdbd
@@ -0,0 +1,240 @@
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]="74b02b18-d1bd-5971-8ece-fc260add97d4")}catch(e){}}();
3
+ import { t as unrefStdin } from "./unref-stdin-SK3WfwxS.js";
4
+ import { a as RUNTIME_SCAN_LOCAL_DEV_PORTS, t as sanitizeRuntimeUrl, u as RUNTIME_SCAN_MAX_STRING_LENGTH } from "./sanitize-runtime-url-crVHbQlW.js";
5
+ import { a as useExitOnCtrlC, c as Spinner, d as useInput, h as Box, i as import_react, m as Text, n as registerMountedTuiRenderer, o as terminalSymbols, p as render, r as useStdoutDimensions, s as isPrintableInput, t as require_jsx_runtime } from "./jsx-runtime-C1t3eR6p.js";
6
+ import * as http from "node:http";
7
+ //#region src/cli/runtime-scan/detect-local-runtime-urls.ts
8
+ const LOCAL_HTTP_HOSTS = ["127.0.0.1", "::1"];
9
+ const probeLocalHttpHost = (port, host) => new Promise((resolve) => {
10
+ let didResolve = false;
11
+ const resolveOnce = (isReachable) => {
12
+ if (didResolve) return;
13
+ didResolve = true;
14
+ resolve(isReachable);
15
+ };
16
+ const request = http.request({
17
+ agent: false,
18
+ host,
19
+ method: "HEAD",
20
+ path: "/",
21
+ port
22
+ }, (response) => {
23
+ response.resume();
24
+ resolveOnce(true);
25
+ });
26
+ request.setTimeout(300, () => request.destroy());
27
+ request.on("error", () => resolveOnce(false));
28
+ request.on("close", () => resolveOnce(false));
29
+ request.end();
30
+ });
31
+ const probeLocalHttpPort = async (port) => {
32
+ if (!(await Promise.all(LOCAL_HTTP_HOSTS.map((host) => probeLocalHttpHost(port, host)))).some(Boolean)) return null;
33
+ return {
34
+ port,
35
+ url: `http://localhost:${port}`
36
+ };
37
+ };
38
+ const detectLocalRuntimeUrls = async (ports = RUNTIME_SCAN_LOCAL_DEV_PORTS) => {
39
+ const probeResults = await Promise.all(ports.map(probeLocalHttpPort));
40
+ const suggestions = [];
41
+ for (const probeResult of probeResults) if (probeResult !== null) suggestions.push(probeResult);
42
+ return suggestions;
43
+ };
44
+ //#endregion
45
+ //#region src/cli/ink/prompt-runtime-scan-url.tsx
46
+ var import_jsx_runtime = require_jsx_runtime();
47
+ const RuntimeScanUrlPrompt = ({ discoverLocalUrls = detectLocalRuntimeUrls, onSubmit }) => {
48
+ const [mode, setMode] = (0, import_react.useState)("select");
49
+ const [suggestions, setSuggestions] = (0, import_react.useState)([]);
50
+ const [isDetecting, setIsDetecting] = (0, import_react.useState)(true);
51
+ const [selectedIndex, setSelectedIndex] = (0, import_react.useState)(0);
52
+ const [url, setUrl] = (0, import_react.useState)("");
53
+ const [validationMessage, setValidationMessage] = (0, import_react.useState)(null);
54
+ const { columns: terminalColumns, rows: terminalRows } = useStdoutDimensions();
55
+ useExitOnCtrlC();
56
+ (0, import_react.useEffect)(() => {
57
+ let isMounted = true;
58
+ discoverLocalUrls().then((detectedSuggestions) => {
59
+ if (!isMounted) return;
60
+ setSuggestions(detectedSuggestions);
61
+ setIsDetecting(false);
62
+ }, () => {
63
+ if (isMounted) setIsDetecting(false);
64
+ });
65
+ return () => {
66
+ isMounted = false;
67
+ };
68
+ }, [discoverLocalUrls]);
69
+ const updateUrl = (nextUrl) => {
70
+ setUrl(nextUrl.slice(0, RUNTIME_SCAN_MAX_STRING_LENGTH));
71
+ setValidationMessage(null);
72
+ };
73
+ useInput((input, key) => {
74
+ if (mode === "select") {
75
+ const optionCount = suggestions.length + 1;
76
+ if (key.escape || input === "q") return onSubmit(null);
77
+ if (key.upArrow || input === "k") return setSelectedIndex(Math.max(0, selectedIndex - 1));
78
+ if (key.downArrow || input === "j") return setSelectedIndex(Math.min(optionCount - 1, selectedIndex + 1));
79
+ if (key.return) {
80
+ const selectedSuggestion = suggestions[selectedIndex];
81
+ if (selectedSuggestion !== void 0) return onSubmit(selectedSuggestion.url);
82
+ setMode("custom");
83
+ return;
84
+ }
85
+ if (isPrintableInput(input) && !key.ctrl && !key.meta) {
86
+ setMode("custom");
87
+ updateUrl(input);
88
+ }
89
+ return;
90
+ }
91
+ if (key.escape) return setMode("select");
92
+ if (key.backspace || key.delete) return updateUrl(url.slice(0, -1));
93
+ if (key.ctrl && input === "u") return updateUrl("");
94
+ if (key.return) {
95
+ const trimmedUrl = url.trim();
96
+ try {
97
+ sanitizeRuntimeUrl(trimmedUrl);
98
+ onSubmit(trimmedUrl);
99
+ } catch {
100
+ setValidationMessage("Enter an absolute URL starting with http:// or https://.");
101
+ }
102
+ return;
103
+ }
104
+ if (isPrintableInput(input) && !key.ctrl && !key.meta) updateUrl(url + input);
105
+ });
106
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
107
+ alignItems: "center",
108
+ height: terminalRows,
109
+ justifyContent: "center",
110
+ width: terminalColumns,
111
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
112
+ borderColor: "magenta",
113
+ borderStyle: "round",
114
+ flexDirection: "column",
115
+ paddingX: 1,
116
+ width: Math.min(terminalColumns, 72),
117
+ children: [
118
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
119
+ color: "magenta",
120
+ bold: true,
121
+ children: "React Doctor"
122
+ }),
123
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
124
+ bold: true,
125
+ children: "Choose an app to scan"
126
+ }),
127
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
128
+ dimColor: true,
129
+ children: "We’ll open Chrome and scan one interaction."
130
+ }),
131
+ mode === "select" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
132
+ flexDirection: "column",
133
+ marginTop: 1,
134
+ children: [
135
+ isDetecting ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
136
+ dimColor: true,
137
+ children: [
138
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
139
+ color: "cyan",
140
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { type: "dots" })
141
+ }),
142
+ " ",
143
+ "Looking for local apps…"
144
+ ]
145
+ }) : null,
146
+ !isDetecting && suggestions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
147
+ dimColor: true,
148
+ children: "No local HTTP apps detected."
149
+ }) : null,
150
+ suggestions.map((suggestion, suggestionIndex) => {
151
+ const isSelected = suggestionIndex === selectedIndex;
152
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
153
+ bold: isSelected,
154
+ color: isSelected ? "cyan" : void 0,
155
+ children: [
156
+ isSelected ? terminalSymbols.pointer : terminalSymbols.pointerSmall,
157
+ " ",
158
+ suggestion.url,
159
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
160
+ dimColor: true,
161
+ children: " detected"
162
+ })
163
+ ]
164
+ }, suggestion.url);
165
+ }),
166
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
167
+ bold: selectedIndex === suggestions.length,
168
+ color: selectedIndex === suggestions.length ? "cyan" : void 0,
169
+ children: [
170
+ selectedIndex === suggestions.length ? terminalSymbols.pointer : terminalSymbols.pointerSmall,
171
+ " ",
172
+ "Enter another URL"
173
+ ]
174
+ }),
175
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
176
+ marginTop: 1,
177
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
178
+ dimColor: true,
179
+ children: "↑↓ choose · Enter continue · Esc cancel"
180
+ })
181
+ })
182
+ ]
183
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
184
+ flexDirection: "column",
185
+ marginTop: 1,
186
+ children: [
187
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
188
+ dimColor: true,
189
+ children: "App URL"
190
+ }),
191
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
192
+ wrap: "truncate-end",
193
+ children: [
194
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
195
+ color: "cyan",
196
+ children: "› "
197
+ }),
198
+ url,
199
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
200
+ inverse: true,
201
+ children: " "
202
+ })
203
+ ]
204
+ }),
205
+ validationMessage === null ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
206
+ color: "red",
207
+ children: validationMessage
208
+ }),
209
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
210
+ marginTop: 1,
211
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
212
+ dimColor: true,
213
+ children: "Enter continue · Esc back · Ctrl+U clear"
214
+ })
215
+ })
216
+ ]
217
+ })
218
+ ]
219
+ })
220
+ });
221
+ };
222
+ const promptRuntimeScanUrl = () => new Promise((resolve) => {
223
+ let disposeRenderer = () => {};
224
+ const submitUrl = (url) => {
225
+ disposeRenderer();
226
+ unrefStdin();
227
+ resolve(url);
228
+ };
229
+ disposeRenderer = registerMountedTuiRenderer(render(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RuntimeScanUrlPrompt, { onSubmit: submitUrl }), {
230
+ alternateScreen: true,
231
+ exitOnCtrlC: false,
232
+ stdin: process.stdin,
233
+ stdout: process.stderr
234
+ }));
235
+ });
236
+ //#endregion
237
+ export { promptRuntimeScanUrl };
238
+
239
+ //# sourceMappingURL=prompt-runtime-scan-url-m88LMtMP.js.map
240
+ //# debugId=74b02b18-d1bd-5971-8ece-fc260add97d4
@@ -1,6 +1,6 @@
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]="157e21d1-5cfe-53a8-82a6-1ad2e4afdfdb")}catch(e){}}();
3
- import { xr as isPlainObject } from "./record-metric-CFfsgcVs.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]="96f6bac3-2133-595d-8c41-bf71dfe19ae2")}catch(e){}}();
3
+ import { Sr as isPlainObject } from "./record-metric-u8youmM2.js";
4
4
  import * as fs$1 from "node:fs";
5
5
  import { parseJSON5 } from "confbox";
6
6
  //#region src/cli/utils/read-object-file.ts
@@ -20,5 +20,5 @@ const readObjectFile = (filePath) => {
20
20
  //#endregion
21
21
  export { readObjectFile as t };
22
22
 
23
- //# sourceMappingURL=read-object-file-Cwhr9OIi.js.map
24
- //# debugId=157e21d1-5cfe-53a8-82a6-1ad2e4afdfdb
23
+ //# sourceMappingURL=read-object-file-Cv41FpZo.js.map
24
+ //# debugId=96f6bac3-2133-595d-8c41-bf71dfe19ae2