react-doctor 0.9.12 → 0.9.13-dev.1239043

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 (52) hide show
  1. package/README.md +34 -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-BsQvH-7I.js → build-section-divider-C09RcJrc.js} +10 -25
  6. package/dist/{ci-B4x4RjKD.js → ci-CUgNjCr-.js} +13 -12
  7. package/dist/cli.js +121 -41
  8. package/dist/{design-A48PNCf_.js → design-CX2j8ubS.js} +4 -4
  9. package/dist/{devtools-DPRVRu3S.js → devtools-CC2PAZ85.js} +4 -4
  10. package/dist/{exit-gracefully-Bk531kS-.js → exit-gracefully-cGJM2g3O.js} +15 -9
  11. package/dist/get-east-asian-width-Bv2TD3Xj.js +444 -0
  12. package/dist/{report-error-Pb2uO8EG.js → handle-error-BCI-Nv3P.js} +18 -68
  13. package/dist/index.d.ts +53 -42
  14. package/dist/index.js +55146 -54688
  15. package/dist/{inspect-CwH84aSA.js → inspect-Dq5krKWG.js} +47 -34
  16. package/dist/{install-sFN_w425.js → install-C0aiZKgf.js} +9 -8
  17. package/dist/{install-doctor-script-DLayXS7q.js → install-doctor-script-CaTIms0r.js} +7 -449
  18. package/dist/{install-github-workflow-Goz-KFqb.js → install-github-workflow-DjPgXVqg.js} +10 -6
  19. package/dist/{install-react-doctor-Bq7dfEBI.js → install-react-doctor-C-PVDWXv.js} +47 -45
  20. package/dist/{run-scan-app-DXBMW54J.js → jsx-runtime-D_A4d39v.js} +281 -2759
  21. package/dist/path-format-DnHpmJwG.js +9 -0
  22. package/dist/{print-branded-header-D_J8Qdsj.js → print-branded-header-Dz0SwyHQ.js} +4 -4
  23. package/dist/project-analysis-worker.d.ts +1 -0
  24. package/dist/project-analysis-worker.js +51905 -0
  25. package/dist/prompt-runtime-scan-url-BXdY2Opw.js +240 -0
  26. package/dist/{read-object-file-Hk79zI91.js → read-object-file-CmMGK1uu.js} +4 -4
  27. package/dist/{record-metric-CsQXJewH.js → record-metric-B6T_Ej33.js} +3285 -6018
  28. package/dist/report-error-DwL3b99q.js +64 -0
  29. package/dist/{report-workflow-result-6n_wSqzA.js → report-workflow-result-5PueDIAr.js} +5 -5
  30. package/dist/{resolve-scope-DP6rYlNO.js → resolve-scope-CTlLl7e6.js} +8 -10
  31. package/dist/{rules-BnIZ4Fq_.js → rules-DEbHKRag.js} +6 -6
  32. package/dist/run-scan-app-D3huvmXJ.js +2517 -0
  33. package/dist/runtime-scan/browser-probe.iife.js +855 -0
  34. package/dist/runtime-scan-CHFAEYg3.js +770 -0
  35. package/dist/sanitize-runtime-url-Bbq40iIp.js +76 -0
  36. package/dist/scan-C7sCm7wi.js +47 -0
  37. package/dist/semver-DFtnEmN-.js +3219 -0
  38. package/dist/{should-fail-scan-gate-DzZuTxim.js → should-fail-scan-gate-CfG_ppAV.js} +188 -187
  39. package/dist/{should-skip-prompts-D1GWG2qN.js → should-skip-prompts-BuNtAVEs.js} +4 -4
  40. package/dist/should-use-tui-B-lCjXVG.js +25 -0
  41. package/dist/skills/improve-threejs/SKILL.md +102 -0
  42. package/dist/skills/performance/SKILL.md +113 -0
  43. package/dist/skills/react-doctor/SKILL.md +6 -0
  44. package/dist/{unref-stdin-0a_0uwC6.js → telemetry-runtime-BF83aBFL.js} +57 -33
  45. package/dist/unref-stdin-SK3WfwxS.js +12 -0
  46. package/dist/{version-Bo5QDp7F.js → version-C27gr4Qj.js} +4 -4
  47. package/dist/{why-BFYbtnm8.js → why-CYRkZ2VY.js} +4 -4
  48. package/dist/with-run-span-CdsXSJgE.js +110 -0
  49. package/package.json +9 -10
  50. package/dist/chunk-q7NCDQ7-.js +0 -28
  51. package/dist/lsp.js +0 -81145
  52. package/dist/scan-CnnXz78m.js +0 -53
@@ -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]="0e2a8ba7-061d-5991-a7ae-c9adab00340e")}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-Bbq40iIp.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-D_A4d39v.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-BXdY2Opw.js.map
240
+ //# debugId=0e2a8ba7-061d-5991-a7ae-c9adab00340e
@@ -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]="c1d9c8d2-780e-54c0-a189-b99318901303")}catch(e){}}();
3
- import { mn as isPlainObject } from "./record-metric-CsQXJewH.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]="846c0e2f-eb25-5791-9f0b-a559abc18de8")}catch(e){}}();
3
+ import { Sr as isPlainObject } from "./record-metric-B6T_Ej33.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-Hk79zI91.js.map
24
- //# debugId=c1d9c8d2-780e-54c0-a189-b99318901303
23
+ //# sourceMappingURL=read-object-file-CmMGK1uu.js.map
24
+ //# debugId=846c0e2f-eb25-5791-9f0b-a559abc18de8