@lariocpt/flawless-react 0.0.0-stage → 0.3.0

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 (143) hide show
  1. package/.agents/skills/flawless-a11y/SKILL.md +113 -0
  2. package/.agents/skills/flawless-api/SKILL.md +159 -0
  3. package/.agents/skills/flawless-api-fixtures/SKILL.md +144 -0
  4. package/.agents/skills/flawless-e2e/SKILL.md +155 -0
  5. package/.agents/skills/flawless-expo/SKILL.md +283 -0
  6. package/.agents/skills/flawless-findings/SKILL.md +116 -0
  7. package/.agents/skills/flawless-load/SKILL.md +112 -0
  8. package/.agents/skills/flawless-nextjs/SKILL.md +198 -0
  9. package/.agents/skills/flawless-perf-harness/SKILL.md +158 -0
  10. package/.agents/skills/flawless-perf-static/SKILL.md +131 -0
  11. package/.agents/skills/flawless-react/SKILL.md +403 -0
  12. package/.agents/skills/flawless-react-rules/SKILL.md +96 -0
  13. package/.agents/skills/flawless-regen/SKILL.md +135 -0
  14. package/.agents/skills/flawless-unit-browser/SKILL.md +178 -0
  15. package/LICENSE +21 -0
  16. package/README.md +608 -2
  17. package/bin/flawless-react +4 -0
  18. package/package.json +67 -4
  19. package/scripts/postinstall.d.mts +46 -0
  20. package/scripts/postinstall.mjs +127 -0
  21. package/src/analyse/authShims.ts +220 -0
  22. package/src/analyse/bootability.ts +257 -0
  23. package/src/analyse/childBridge.ts +302 -0
  24. package/src/analyse/childrenIntoSlot.ts +66 -0
  25. package/src/analyse/compoundFamily.ts +100 -0
  26. package/src/analyse/dataExports.ts +200 -0
  27. package/src/analyse/extractChildAttrs.ts +112 -0
  28. package/src/analyse/extractDataDeps.ts +857 -0
  29. package/src/analyse/extractDisclosures.ts +186 -0
  30. package/src/analyse/extractFetchCalls.ts +81 -0
  31. package/src/analyse/extractFlows.ts +239 -0
  32. package/src/analyse/extractGuards.ts +270 -0
  33. package/src/analyse/extractHooks.ts +237 -0
  34. package/src/analyse/extractInteractions.ts +1421 -0
  35. package/src/analyse/extractLogging.ts +45 -0
  36. package/src/analyse/extractNativeA11y.ts +138 -0
  37. package/src/analyse/extractPredicates.ts +784 -0
  38. package/src/analyse/extractPropUsage.ts +162 -0
  39. package/src/analyse/extractProps.ts +1212 -0
  40. package/src/analyse/extractRenderMode.ts +165 -0
  41. package/src/analyse/extractRootTag.ts +117 -0
  42. package/src/analyse/extractState.ts +361 -0
  43. package/src/analyse/extractStaticText.ts +212 -0
  44. package/src/analyse/extractVariants.ts +186 -0
  45. package/src/analyse/harvestApiEndpoints.ts +284 -0
  46. package/src/analyse/hostProps.ts +185 -0
  47. package/src/analyse/hostTag.ts +72 -0
  48. package/src/analyse/htmlContentModel.ts +94 -0
  49. package/src/analyse/index.ts +744 -0
  50. package/src/analyse/mountPathCalls.ts +442 -0
  51. package/src/analyse/nativeContentModel.ts +129 -0
  52. package/src/analyse/nativeDialect.ts +83 -0
  53. package/src/analyse/nativeProps.ts +339 -0
  54. package/src/analyse/ownReturns.ts +31 -0
  55. package/src/analyse/parseFile.ts +919 -0
  56. package/src/analyse/pos.ts +8 -0
  57. package/src/analyse/providerWraps.ts +1977 -0
  58. package/src/analyse/pureModule.ts +88 -0
  59. package/src/analyse/reexportTable.ts +148 -0
  60. package/src/analyse/refs.ts +195 -0
  61. package/src/analyse/renderPath.ts +441 -0
  62. package/src/analyse/resolveDepReturns.ts +370 -0
  63. package/src/analyse/resolveIndexKeys.ts +98 -0
  64. package/src/analyse/resolveModule.ts +431 -0
  65. package/src/analyse/resolveTagRootTags.ts +103 -0
  66. package/src/analyse/serverActionReturns.ts +213 -0
  67. package/src/analyse/sourceCache.ts +263 -0
  68. package/src/analyse/spreadSiblings.ts +98 -0
  69. package/src/analyse/walkChildren.ts +98 -0
  70. package/src/analyse/zodSchema.ts +424 -0
  71. package/src/bin.ts +23 -0
  72. package/src/changed.ts +221 -0
  73. package/src/cli.ts +560 -0
  74. package/src/cliFlags.ts +281 -0
  75. package/src/core.ts +1229 -0
  76. package/src/docLine.ts +122 -0
  77. package/src/emitPaths.ts +51 -0
  78. package/src/expo/detect.ts +184 -0
  79. package/src/expo/refusal.ts +62 -0
  80. package/src/expo/routes.ts +145 -0
  81. package/src/index.ts +95 -0
  82. package/src/mcp/analysisTools.ts +720 -0
  83. package/src/mcp/infoTools.ts +135 -0
  84. package/src/mcp/protocol.ts +130 -0
  85. package/src/mcp/run.ts +269 -0
  86. package/src/mcp/runTools.ts +362 -0
  87. package/src/mcp/server.ts +279 -0
  88. package/src/mcp/spec.ts +86 -0
  89. package/src/mcp/support.ts +268 -0
  90. package/src/mcp/tools.ts +75 -0
  91. package/src/nextjs/apiRoutes.ts +116 -0
  92. package/src/nextjs/detect.ts +397 -0
  93. package/src/nextjs/emit.ts +106 -0
  94. package/src/nextjs/liveSpec.ts +79 -0
  95. package/src/nextjs/mswHandlers.ts +55 -0
  96. package/src/nextjs/providerWrapper.ts +603 -0
  97. package/src/nextjs/routes.ts +86 -0
  98. package/src/nextjs/swagger.ts +32 -0
  99. package/src/packageJson.ts +414 -0
  100. package/src/platform.ts +18 -0
  101. package/src/prompt.ts +132 -0
  102. package/src/reactCompiler.ts +165 -0
  103. package/src/reporters/findings.ts +156 -0
  104. package/src/reporters/report.ts +463 -0
  105. package/src/runner/runTests.ts +402 -0
  106. package/src/scaffold/adoptStyle.ts +181 -0
  107. package/src/scaffold/index.ts +253 -0
  108. package/src/scaffold/openapi.ts +183 -0
  109. package/src/scaffold/templates.ts +2379 -0
  110. package/src/scaffold-tests/index.ts +463 -0
  111. package/src/scaffold-tests/mockValues.ts +208 -0
  112. package/src/scaffold-tests/mocks.ts +794 -0
  113. package/src/scaffold-tests/nativeIndex.ts +52 -0
  114. package/src/scaffold-tests/nativeTemplates.ts +1528 -0
  115. package/src/scaffold-tests/postDispatch.ts +152 -0
  116. package/src/scaffold-tests/registry.ts +443 -0
  117. package/src/scaffold-tests/selectors.ts +493 -0
  118. package/src/scaffold-tests/selectorsNative.ts +273 -0
  119. package/src/scaffold-tests/stamp.ts +79 -0
  120. package/src/scaffold-tests/templates.ts +3578 -0
  121. package/src/skills/cli.ts +248 -0
  122. package/src/skills/compat.ts +166 -0
  123. package/src/skills/data.ts +192 -0
  124. package/src/skills/md.d.ts +7 -0
  125. package/src/skills/menu.ts +55 -0
  126. package/src/skills/spec.ts +227 -0
  127. package/src/suiteScripts.ts +110 -0
  128. package/src/tasks/a11yNative.ts +281 -0
  129. package/src/tasks/a11yScan.ts +67 -0
  130. package/src/tasks/biomeRunner.ts +301 -0
  131. package/src/tasks/biomeSweep.ts +166 -0
  132. package/src/tasks/e2eExpo.ts +436 -0
  133. package/src/tasks/e2eRoutes.ts +756 -0
  134. package/src/tasks/eslintReactRules.ts +67 -0
  135. package/src/tasks/index.ts +24 -0
  136. package/src/tasks/loadExpo.ts +273 -0
  137. package/src/tasks/loadPipes.ts +750 -0
  138. package/src/tasks/perfHarness.ts +145 -0
  139. package/src/tasks/staticPerfAnalysis.ts +510 -0
  140. package/src/tasks/types.ts +1 -0
  141. package/src/tasks/unitAndBrowser.ts +462 -0
  142. package/src/types.ts +1419 -0
  143. package/src/version.ts +12 -0
@@ -0,0 +1,281 @@
1
+ // The CLI's flag inventory, as data.
2
+ //
3
+ // This list used to exist twice: as prose inside cli.ts's HELP literal, and as
4
+ // the if-chain in parseArgs. Two copies of the same list is the defect class
5
+ // this project keeps finding in its own docs — and the website's CLI reference
6
+ // had already drifted from it, documenting 25 flags while --roots, --exclude
7
+ // and --no-default-excludes went unmentioned for a whole release.
8
+ //
9
+ // So: one table. HELP renders from it, `--flags` prints it for consumers that
10
+ // cannot import it (the website repo lints its own reference page by running
11
+ // the published binary), and tests/docsLint.test.ts checks the shipped prose
12
+ // against it. parseArgs keeps its own if-chain — this is an INVENTORY, not a
13
+ // second parser, and its `unknown flag` branch is still the runtime guard. The
14
+ // two are held together by a test that fails when a flag is added to one and
15
+ // not the other.
16
+ //
17
+ // Kept free of every other import: --help and --flags must answer without
18
+ // paying for the TypeScript compiler that core.ts drags in (FR-031).
19
+
20
+ export interface FlagDoc {
21
+ /** The long form, e.g. "--tasks". */
22
+ name: string;
23
+ /** The short form, e.g. "-h". */
24
+ alias?: string;
25
+ /** The value placeholder as help renders it; absent means a boolean flag. */
26
+ value?: string;
27
+ /** Help text — an array is rendered as continuation lines. */
28
+ summary: string | string[];
29
+ }
30
+
31
+ export const FLAGS: readonly FlagDoc[] = [
32
+ {
33
+ name: "--out",
34
+ value: "<dir>",
35
+ summary: "Output directory (default: ./.flawless)",
36
+ },
37
+ {
38
+ name: "--tasks",
39
+ value: "<csv>",
40
+ summary: [
41
+ "Comma-separated task ids to run (skip the interactive menu).",
42
+ "Available: perf-harness, unit-browser, perf-static, a11y,",
43
+ "react-rules, e2e, load",
44
+ ],
45
+ },
46
+ {
47
+ name: "--roots",
48
+ value: "<mode>",
49
+ summary: [
50
+ "primary (default) analyses each file's main component;",
51
+ "exported emits a tree per exported component, which is what a",
52
+ "whole-app sweep needs (a shadcn card.tsx exports 7 of them).",
53
+ ],
54
+ },
55
+ {
56
+ name: "--exclude",
57
+ value: "<glob>",
58
+ summary: [
59
+ "Skip matching files (repeatable). Appended to the defaults,",
60
+ "which already skip *.flawless.test.*, *.test.*, *.spec.*,",
61
+ "*.stories.*, *.d.ts, node_modules, .next, dist, build,",
62
+ "coverage, flawless/. A non-default --out is NOT excluded.",
63
+ ],
64
+ },
65
+ {
66
+ name: "--no-default-excludes",
67
+ summary: "Drop those defaults (then a glob can match generated specs).",
68
+ },
69
+ {
70
+ name: "--colocate",
71
+ summary: [
72
+ "Emit unit specs beside the analysed sources as",
73
+ "<name>.flawless.test.tsx (existing colocated specs are kept",
74
+ "unless --force). The flawless/ dir keeps config + mocks.",
75
+ ],
76
+ },
77
+ {
78
+ name: "--ci",
79
+ summary: "Shorthand for --no-interactive --json.",
80
+ },
81
+ {
82
+ name: "--no-interactive",
83
+ summary: [
84
+ "Never prompt; require a positional (or --nextjs). Without",
85
+ "--tasks the run does perf-harness alone.",
86
+ ],
87
+ },
88
+ {
89
+ name: "--run-tests",
90
+ summary: "After generating, run the produced test suites.",
91
+ },
92
+ {
93
+ name: "--no-inline-summary",
94
+ summary: "Don't drop <Component>.flawless.json next to each source file.",
95
+ },
96
+ {
97
+ name: "--json",
98
+ summary: "Print machine-readable JSON summary to stdout.",
99
+ },
100
+ {
101
+ name: "--nextjs",
102
+ value: "[<path>]",
103
+ summary: [
104
+ "Treat <path> (or cwd) as a Next.js project: detect router style,",
105
+ "emit MSW handlers + swagger from app/api or pages/api, auto-set the",
106
+ "app resolver from app/layout.tsx or pages/_app.tsx, merge generated",
107
+ "deps into the project's package.json (devDependencies) and place",
108
+ "everything under <nextRoot>/flawless/.",
109
+ ],
110
+ },
111
+ {
112
+ name: "--expo",
113
+ value: "[<path>]",
114
+ summary: [
115
+ "Treat <path> (or cwd) as an Expo project: read its SDK major,",
116
+ "expo-router root, React Compiler and NativeWind settings, and",
117
+ "place everything under <expoRoot>/flawless/. Mutually exclusive",
118
+ "with --nextjs.",
119
+ ],
120
+ },
121
+ {
122
+ name: "--app-resolver",
123
+ value: "<file>",
124
+ summary: [
125
+ "Override the auto-detected Next.js app resolver (alias for --provider",
126
+ "in Next.js mode; the file must default-export a wrapper component).",
127
+ ],
128
+ },
129
+ {
130
+ name: "--swagger-url",
131
+ value: "<url>",
132
+ summary: [
133
+ "Fetch an OpenAPI spec from a live URL (e.g.",
134
+ "http://localhost:3000/api/docs from next-swagger-doc) and prefer it",
135
+ "over static AST inference. In --nextjs mode the default URL above is",
136
+ "tried automatically with a short timeout; pass --swagger-url to",
137
+ "force a specific URL or skip the auto-try via --swagger-url=off.",
138
+ ],
139
+ },
140
+ {
141
+ name: "--depth",
142
+ value: "N",
143
+ summary: "Levels of locally-imported children to follow (default 3)",
144
+ },
145
+ {
146
+ name: "--variants",
147
+ value: "N",
148
+ summary: "Variant rows per component (default 5)",
149
+ },
150
+ {
151
+ name: "--changed",
152
+ value: "[REF]",
153
+ summary: [
154
+ "After generating, run only the specs affected by files",
155
+ "changed since REF (default HEAD) — including e2e routes",
156
+ "whose page renders a changed component",
157
+ ],
158
+ },
159
+ {
160
+ name: "--heaps",
161
+ value: "MODE",
162
+ summary: [
163
+ "V8 heap snapshots in the profile suite:",
164
+ "off | stress (default) | all. A snapshot is tens of MB",
165
+ "and one is taken either side of every scenario",
166
+ ],
167
+ },
168
+ {
169
+ name: "--include-children",
170
+ summary: "Walk children (default true). Pass --include-children=false to skip.",
171
+ },
172
+ {
173
+ name: "--props",
174
+ value: "'<json>'",
175
+ summary: "Override the synthesised default props for the first entry.",
176
+ },
177
+ {
178
+ name: "--provider",
179
+ value: "<file>",
180
+ summary: "Path to a .tsx file default-exporting a Provider wrapper.",
181
+ },
182
+ {
183
+ name: "--api",
184
+ value: "<spec>",
185
+ summary: "Path to an OpenAPI/Swagger spec; scaffolds a mock server.",
186
+ },
187
+ {
188
+ name: "--force",
189
+ summary: [
190
+ "Also regenerate what a re-run keeps: colocated specs,",
191
+ "e2e route specs, the derived provider wrapper.",
192
+ "(A plain re-run already refreshes the out-dir harness.)",
193
+ ],
194
+ },
195
+ {
196
+ name: "--report",
197
+ summary: "Emit scripts/report.mjs to aggregate run output.",
198
+ },
199
+ {
200
+ name: "--help",
201
+ alias: "-h",
202
+ summary: "Show this help.",
203
+ },
204
+ {
205
+ name: "--version",
206
+ alias: "-V",
207
+ summary: "Show version.",
208
+ },
209
+ ];
210
+
211
+ /** Every long flag name, for coverage checks and `--flags`. */
212
+ export const FLAG_NAMES: readonly string[] = FLAGS.map((f) => f.name);
213
+
214
+ /**
215
+ * The parse-only surfaces, kept OUT of FLAGS on purpose.
216
+ *
217
+ * They are real and public — the website's CI is built on them — but they are
218
+ * not run options: main() answers them before parseArgs is ever called, so
219
+ * parseArgs rejects them like any other unknown flag, and listing them among
220
+ * the options would put them in the round-trip that proves every FLAGS entry
221
+ * parses. Documented in their own block instead, because a public surface CI
222
+ * depends on should not be undiscoverable.
223
+ */
224
+ export const MAINTENANCE_FLAGS: readonly FlagDoc[] = [
225
+ {
226
+ name: "--check",
227
+ value: "'<line>'",
228
+ summary: [
229
+ "Parse documented invocations without running them, and exit",
230
+ "nonzero if any fails. Opens no file and spawns nothing.",
231
+ ],
232
+ },
233
+ {
234
+ name: "--flags",
235
+ summary: "Print the flag inventory above, one per line.",
236
+ },
237
+ ];
238
+
239
+ /** `--out <dir>`, `-h, --help` — the left column, as help prints it. */
240
+ export function flagLabel(f: FlagDoc): string {
241
+ const long = f.value === undefined ? f.name : `${f.name} ${f.value}`;
242
+ return f.alias === undefined ? long : `${f.alias}, ${long}`;
243
+ }
244
+
245
+ // The description column. Every continuation line in the block aligns here too,
246
+ // which is what lets the whole Options section render from the table.
247
+ const DESC_COL = 25;
248
+
249
+ const PRELUDE = `flawless-react — multi-task quality kit for React components
250
+
251
+ Usage:
252
+ flawless-react <entry-or-glob> [options]
253
+ flawless-react (interactive menu)
254
+ flawless-react skills <list|install> (the agent skills this binary carries)
255
+
256
+ Positional:
257
+ <entry-or-glob> A .tsx file path or a glob (e.g. "src/**/*.tsx").
258
+ Each matched file is analysed as its own entry component.
259
+
260
+ Options:
261
+ `;
262
+
263
+ /** Exported for the `skills` subcommand's own help, so both surfaces lay the
264
+ * flags out in one column with one rule rather than two hand-set tables. */
265
+ export function renderBlock(flags: readonly FlagDoc[]): string {
266
+ let out = "";
267
+ for (const f of flags) {
268
+ const lines = typeof f.summary === "string" ? [f.summary] : f.summary;
269
+ out += ` ${flagLabel(f).padEnd(DESC_COL - 2)}${lines[0]}\n`;
270
+ for (const cont of lines.slice(1)) out += `${" ".repeat(DESC_COL)}${cont}\n`;
271
+ }
272
+ return out;
273
+ }
274
+
275
+ /** The `--help` text. The Options block is byte-for-byte what the
276
+ * hand-maintained literal produced; the Maintenance block is new. */
277
+ export function renderHelp(): string {
278
+ return `${PRELUDE}${renderBlock(FLAGS)}
279
+ Maintenance (parse-only — these never analyse, generate or run anything):
280
+ ${renderBlock(MAINTENANCE_FLAGS)}`;
281
+ }