flet-box 1.1.2 → 1.1.3

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 (154) hide show
  1. package/AGENTS_FOR_CODE_GEN.md +284 -0
  2. package/CONTRIBUTING.md +238 -0
  3. package/README.md +2 -2
  4. package/bin/cli.js +88 -1
  5. package/bin/commands/auditFix.js +181 -27
  6. package/bin/commands/checkApi.js +14 -3
  7. package/bin/commands/checkStructure.js +368 -0
  8. package/bin/commands/checkSyntax.js +293 -0
  9. package/bin/commands/checkUi.js +666 -14
  10. package/bin/commands/create.js +14 -0
  11. package/bin/commands/createBundle.js +2 -2
  12. package/bin/commands/metrics.js +448 -0
  13. package/bin/commands/release.js +18 -0
  14. package/bin/commands/report.js +849 -0
  15. package/bin/commands/tools.js +76 -0
  16. package/bin/commands/unpack.js +39 -11
  17. package/bin/commands/verify.js +879 -0
  18. package/bin/mcp.js +280 -0
  19. package/bin/utils/contract.js +27 -0
  20. package/bin/utils/dtsProps.js +5 -1
  21. package/bin/utils/migrationGuide.js +146 -0
  22. package/bin/utils/moduleExports.js +9 -5
  23. package/bin/utils/templates.js +225 -18
  24. package/bin/utils/toolkit.js +191 -0
  25. package/docs/README.md +5 -1
  26. package/docs/arquitectura.md +1 -1
  27. package/docs/cli/README.md +168 -2
  28. package/docs/guides/README.md +6 -0
  29. package/docs/guides/accessibility.md +2 -1
  30. package/docs/guides/ai-toolkit.md +166 -0
  31. package/docs/guides/compatibility.md +1 -1
  32. package/docs/guides/migration.md +92 -0
  33. package/docs/guides/minification-and-protection.md +2 -1
  34. package/docs/guides/mobile-and-platforms.md +1 -1
  35. package/docs/guides/online-updates.md +2 -0
  36. package/docs/server/deployment.md +1 -1
  37. package/docs/tools/styling.md +2 -2
  38. package/docs/tools/theme.md +139 -4
  39. package/docs/widget/Accordion.md +74 -8
  40. package/docs/widget/AdMob.md +68 -3
  41. package/docs/widget/AdSense.md +67 -2
  42. package/docs/widget/AlertDialog.md +1 -1
  43. package/docs/widget/AnimatedBox.md +80 -39
  44. package/docs/widget/AnimatedText.md +74 -18
  45. package/docs/widget/Audio.md +73 -14
  46. package/docs/widget/Avatar.md +69 -4
  47. package/docs/widget/Badge.md +68 -3
  48. package/docs/widget/BottomSheet.md +2 -2
  49. package/docs/widget/Button.md +69 -3
  50. package/docs/widget/Card.md +69 -4
  51. package/docs/widget/Carousel.md +67 -2
  52. package/docs/widget/Chart.md +67 -2
  53. package/docs/widget/Checkbox.md +74 -8
  54. package/docs/widget/Chip.md +68 -3
  55. package/docs/widget/CircularBar.md +74 -15
  56. package/docs/widget/CircularChart.md +71 -10
  57. package/docs/widget/CodeViewer.md +67 -2
  58. package/docs/widget/Column.md +68 -3
  59. package/docs/widget/Container.md +68 -3
  60. package/docs/widget/DataTable.md +67 -2
  61. package/docs/widget/Divider.md +67 -2
  62. package/docs/widget/DraggBox.md +67 -2
  63. package/docs/widget/Dropdown.md +76 -10
  64. package/docs/widget/DroppBox.md +67 -2
  65. package/docs/widget/FloatingActionButton.md +68 -3
  66. package/docs/widget/GridView.md +67 -2
  67. package/docs/widget/Icon.md +71 -5
  68. package/docs/widget/Image.md +68 -3
  69. package/docs/widget/Input.md +68 -3
  70. package/docs/widget/Inspector.md +2 -2
  71. package/docs/widget/InstallButton.md +73 -13
  72. package/docs/widget/ListTile.md +69 -3
  73. package/docs/widget/ListView.md +67 -2
  74. package/docs/widget/Maps.md +68 -3
  75. package/docs/widget/Markdown.md +74 -15
  76. package/docs/widget/MatrixRain.md +72 -11
  77. package/docs/widget/Menu.md +209 -0
  78. package/docs/widget/Modal.md +3 -3
  79. package/docs/widget/Pagination.md +68 -3
  80. package/docs/widget/ParallaxBox.md +72 -12
  81. package/docs/widget/ProgressBar.md +69 -4
  82. package/docs/widget/QRCode.md +67 -2
  83. package/docs/widget/README.md +54 -50
  84. package/docs/widget/Radio.md +76 -10
  85. package/docs/widget/Rating.md +70 -6
  86. package/docs/widget/Row.md +68 -3
  87. package/docs/widget/Skeleton.md +68 -3
  88. package/docs/widget/Slider.md +75 -9
  89. package/docs/widget/SnackBar.md +2 -2
  90. package/docs/widget/Stack.md +68 -3
  91. package/docs/widget/Stepper.md +68 -3
  92. package/docs/widget/Switch.md +74 -8
  93. package/docs/widget/Text.md +71 -4
  94. package/docs/widget/ThemePicker.md +197 -0
  95. package/docs/widget/Tooltip.md +72 -7
  96. package/docs/widget/TreeView.md +70 -10
  97. package/docs/widget/Video.md +71 -10
  98. package/package.json +10 -3
  99. package/skills/fletbox-design/SKILL.md +89 -5
  100. package/skills/fletbox-motion/SKILL.md +1 -1
  101. package/skills/fletbox-rules/SKILL.md +56 -4
  102. package/src/core/runApp.js +12 -0
  103. package/src/index.d.ts +374 -101
  104. package/src/index.js +9 -0
  105. package/src/navigations/AdaptiveScaffold.js +2 -2
  106. package/src/navigations/BottomNavigation.js +1 -1
  107. package/src/navigations/Scaffold.js +18 -6
  108. package/src/tools/useState.js +11 -4
  109. package/src/utils/colors.js +275 -0
  110. package/src/utils/errorBoundary.js +288 -0
  111. package/src/utils/index.js +10 -2
  112. package/src/utils/stackPosition.js +39 -24
  113. package/src/utils/syntaxHighlight.js +4 -1
  114. package/src/utils/themes.js +279 -3
  115. package/src/widget-factory/addChildren.js +17 -10
  116. package/src/widget-factory/assignProps.js +18 -6
  117. package/src/widget-factory/createWidget.js +7 -0
  118. package/src/widget-factory/deprecations.js +77 -0
  119. package/src/widget-factory/translateProps.js +11 -1
  120. package/src/widget-factory/warnings.js +1 -27
  121. package/src/widget-factory/widgetFactory.js +59 -17
  122. package/src/widgets/Accordion.js +21 -7
  123. package/src/widgets/Badge.js +11 -2
  124. package/src/widgets/Button.js +15 -3
  125. package/src/widgets/Carousel.js +12 -4
  126. package/src/widgets/Chart.js +7 -2
  127. package/src/widgets/Checkbox.js +1 -2
  128. package/src/widgets/Chip.js +24 -10
  129. package/src/widgets/CircularBar.js +9 -3
  130. package/src/widgets/CircularChart.js +5 -3
  131. package/src/widgets/Container.js +6 -0
  132. package/src/widgets/Divider.js +3 -1
  133. package/src/widgets/DraggBox.js +9 -0
  134. package/src/widgets/Dropdown.js +3 -3
  135. package/src/widgets/DroppBox.js +5 -0
  136. package/src/widgets/FloatingActionButton.js +1 -1
  137. package/src/widgets/Icon.js +5 -1
  138. package/src/widgets/InstallButton.js +4 -2
  139. package/src/widgets/Markdown.js +171 -103
  140. package/src/widgets/Menu.js +340 -0
  141. package/src/widgets/Modal.js +7 -1
  142. package/src/widgets/Pagination.js +10 -5
  143. package/src/widgets/ProgressBar.js +5 -4
  144. package/src/widgets/QRCode.js +4 -0
  145. package/src/widgets/Radio.js +1 -2
  146. package/src/widgets/Rating.js +9 -0
  147. package/src/widgets/Slider.js +4 -1
  148. package/src/widgets/SnackBar.js +2 -2
  149. package/src/widgets/Switch.js +1 -2
  150. package/src/widgets/Text.js +9 -5
  151. package/src/widgets/ThemePicker.js +234 -0
  152. package/src/widgets/TreeView.js +2 -1
  153. package/src/widgets/index.js +2 -0
  154. package/docs/CONTRIBUTING.md +0 -156
package/docs/README.md CHANGED
@@ -18,6 +18,8 @@ This documentation is one continuous book. Start at **Chapter 0** and follow the
18
18
  | 11 | [The CLI](cli/README.md) | Create, run, and build projects with `flet-box` | Intermediate |
19
19
  | 12 | [Clean UI](guides/clean-ui.md) | The four skills every app ships with, the design system they hold, and the gate that enforces it | Intermediate |
20
20
  | 13 | [Accessibility](guides/accessibility.md) | The focus ring, the keyboard pass over every press, the roles the widgets declare, and the overlays that hold the keyboard | Intermediate |
21
+ | 14 | [Migrate an app to a newer FletBox](guides/migration.md) | What changed between releases, and the codemod that writes it for you | Intermediate |
22
+ | 15 | [The AI toolkit](guides/ai-toolkit.md) | The map from a question to the command, the per-file report, and the MCP server | Intermediate |
21
23
  | A | [Appendices](guides/minification-and-protection.md) | Minification, mobile, compatibility, embedding, online updates (OTA) | Advanced |
22
24
 
23
25
  > **Levels.** *Beginner:* start here and read in order. *Intermediate:* continue in order — you are comfortable with widgets. *Advanced:* for when you ship, skip on a first read.
@@ -56,6 +58,8 @@ Front cover (this page)
56
58
  → The CLI · cli/README.md
57
59
  → Clean UI · guides/clean-ui.md
58
60
  → Accessibility · guides/accessibility.md
61
+ → Migrating · guides/migration.md
62
+ → The AI toolkit · guides/ai-toolkit.md
59
63
  → Appendices (minification → mobile → compatibility → embedding → online updates)
60
64
  → The end of the book
61
65
  ```
@@ -71,7 +75,7 @@ Front cover (this page)
71
75
 
72
76
  - [Server toolkit](server/README.md) — Express/SQLite/Redis backend helpers (separate toolkit).
73
77
  - [Architecture](arquitectura.md) — how the framework is built inside.
74
- - [Contributing](CONTRIBUTING.md) — for people who add code or docs to FletBox.
78
+ - [Contributing](../CONTRIBUTING.md) — for people who add code or docs to FletBox.
75
79
 
76
80
  ## Read this book as an app
77
81
 
@@ -161,4 +161,4 @@ and strips dev warnings from the shipped output. See
161
161
  - [Routing](guides/router.md)
162
162
  - [Utilities](guides/utilities.md)
163
163
  - [Frontend services](guides/frontend-services.md)
164
- - [Contributing](CONTRIBUTING.md)
164
+ - [Contributing](../CONTRIBUTING.md)
@@ -2,13 +2,13 @@
2
2
 
3
3
  The FletBox CLI helps you create, run, expand, and build FletBox applications from the terminal.
4
4
 
5
- You do not need to create every folder by hand. The CLI can create a working project, add screens and components, start a development server, and prepare a production bundle.
5
+ You do not need to create every folder by hand. The CLI can create a working project, add screens and components, start a development server, prepare a production bundle, and check the code against the API the installed framework really has.
6
6
 
7
7
  ## Before you start
8
8
 
9
9
  Install:
10
10
 
11
- - Node.js 18 or newer.
11
+ - Node.js 20.9 or newer.
12
12
  - npm.
13
13
  - A terminal such as Terminal, iTerm, PowerShell, or the VS Code terminal.
14
14
 
@@ -590,6 +590,156 @@ alongside the app, and that file says so.
590
590
  The full contract — the 21 rules, every finding code, and how to fix one — is
591
591
  [Chapter 12, Clean UI](../guides/clean-ui.md).
592
592
 
593
+ ## Look up the API the app really has
594
+
595
+ `flet-box check-api` reads your own `src/` and reports every name that does not
596
+ belong to the installed package: a widget that does not exist, a prop the real
597
+ widget never reads, a widget called with a positional string instead of a props
598
+ object, an import from another framework, and a broken import between two of your
599
+ own modules — the last two resolved statically, so it works offline and in CI.
600
+
601
+ It imports the package's barrel for real and reads its own types, so it cannot
602
+ judge your code against an API you do not have.
603
+
604
+ ```bash
605
+ flet-box check-api # scan ./src
606
+ flet-box check-api --props Button # print one widget's real props
607
+ flet-box check-api --list # print every public export
608
+ flet-box check-api --emit-api # write .fletbox/api/cheatsheet.md
609
+ flet-box check-api --json # the findings as data
610
+ flet-box check-api --root ../my-app # scan another project
611
+ ```
612
+
613
+ Aliases: `flet-box check`, `checkApi`, `doctor`. It exits `1` when it finds an
614
+ error, which is what lets it be the `api` gate inside `flet-box verify` and the
615
+ `npm run check` a created app ships.
616
+
617
+ `--emit-api` writes the cheatsheet an assistant should read before it writes any
618
+ code for the app: every widget, every prop the package can prove, and a prop that
619
+ has been renamed marked `(deprecated → onPress)` — the old spelling still works,
620
+ so nothing else will tell you it is the one being retired. `flet-box create`
621
+ generates the file at scaffold time; after a version bump, regenerate it with the
622
+ command above. It is the API at that version, not the one you remember.
623
+
624
+ ## Unpack a widget
625
+
626
+ Every prop lives in four places, and they can disagree: the type declaration, the
627
+ engine's prop registry, the widget's own source, and its doc page.
628
+ `flet-box unpack <Widget>` cross-checks the four and labels each disagreement
629
+ instead of hiding it:
630
+
631
+ | Label | What it means |
632
+ | --- | --- |
633
+ | `DEAD` | Declared in the interface, routed by the engine nowhere and read by the widget nowhere — writing it has no effect. |
634
+ | `INVENTED` | The widget reads it, and no interface declares it. |
635
+ | `UNDOCUMENTED` | The engine handles it for this widget and the interface hides it — the editor underlines a call that works. |
636
+ | `DOC-ONLY` | The doc page promises it and the code has never heard of it. |
637
+ | `CODE-ONLY` | The code accepts it and the doc page never mentions it. |
638
+
639
+ ```bash
640
+ flet-box unpack Button # what Button really accepts, prop by prop
641
+ flet-box unpack Button --example # a paste-ready call using only verified props
642
+ flet-box unpack Modal --diff # declared vs real, and what disagrees
643
+ flet-box unpack Button --json # the same contract as data
644
+ flet-box unpack --all # every widget → .fletbox/api/api.json
645
+ flet-box unpack --all --md # and the readable api.md beside it
646
+ flet-box unpack --all --json # the whole surface on stdout, writing nothing
647
+ flet-box unpack Button --root ../my-app # read another project's package
648
+ ```
649
+
650
+ `--example` is the answer to "what can I paste". It is built only from props the
651
+ four surfaces agree on, never carries a renamed one, samples no blind `width` or
652
+ `height` (a number pasted into `Switch` collapses it), and never drops a required
653
+ prop — so the call it prints runs.
654
+
655
+ `--all` writes the whole verified surface to `.fletbox/api/api.json`, the file a
656
+ created app's assistant reads as data; `--md` puts `api.md` beside it and
657
+ `--json` prints the same tree to stdout instead of writing anything. `npm run
658
+ api` in a created app is `unpack --all --md`.
659
+
660
+ ## Verify everything at once
661
+
662
+ `flet-box verify` is the single command: it parses every module, then runs the
663
+ anti-hallucination check, the type check (the project's own `jsconfig.json`
664
+ through TypeScript — the same service the editor uses, so a widget declared as
665
+ a bare `HTMLElement` and the `widget.update({ … })` call it rejects are a gate
666
+ failure with a line, not a squiggle to be ignored), the clean-UI check, the
667
+ structural check and the prop contract **in parallel**, and then runs whichever
668
+ test scripts the project declares — one report, one exit code. It is the command
669
+ to run after every edit: the report names the gate, the file at `line:column`
670
+ and what to do about it, instead of making you run seven commands and remember
671
+ which one failed.
672
+
673
+ ```bash
674
+ flet-box verify # every gate and every suite, one report
675
+ flet-box verify --only syntax # one gate: syntax | api | types | ui | structure | surface | tests
676
+ flet-box verify --only tests # the project's own suites, nothing else
677
+ flet-box verify --fix # the mechanical repair first, then the gates
678
+ flet-box verify --json # the report as data
679
+ flet-box verify --watch # re-runs the fast gates on every edit (no suites)
680
+ flet-box verify --no-tests # the static gates only; run the suites yourself
681
+ flet-box run --verify # the same, while the dev server runs
682
+ ```
683
+
684
+ Every generated app ships it as `npm run verify`. The gates read the installed
685
+ package, so they cannot judge your code against an API you do not have.
686
+
687
+ The gates, and what each one owns:
688
+
689
+ | Gate | What it proves |
690
+ | --- | --- |
691
+ | `syntax` | Every module loads. Each `.js`/`.mjs`/`.cjs` outside `node_modules`, `www` and `dist` is handed to `node --check` — the parser the runtime uses — and a parse error is reported at `file:line:column` with the offending source line, a caret under the character and a hint: an unclosed brace, a backtick that never closes, a smart quote that only looks like a quote. |
692
+ | `api` | The code only names widgets and props that exist, and its own modules resolve each other. |
693
+ | `ui` | The code is on the tokens, on the scale, and every control has a name. |
694
+ | `structure` | Two of your modules do not import each other in a circle, every module lives where the project expects it, and no screen writes the DOM by hand. |
695
+ | `surface` | Every prop a widget reads is declared, and every declared prop is read. |
696
+ | `tests` | The project's own suites run and pass. `test`, `test:browser` and `test:visual` are run one after another when `package.json` declares them; a failing suite's own last output is the finding, which is where the rule is named. A project that declares none — a generated app — gets a skipped step, not a green one. |
697
+
698
+ The parse gate runs first because the other four read code as text. A file that
699
+ does not load is a line, not a finding about an invented prop, and telling the
700
+ two apart is the difference between one edit and a guess.
701
+
702
+ Every finding prints the same four things: the file at `line:column`, the code,
703
+ what is wrong and a `→` suggestion. Warnings are printed too, under *what to
704
+ review* — they do not fail the run, but they name the same line, which is the
705
+ only form in which an agent can act on them.
706
+
707
+ `--fix` runs `flet-box audit-fix` first: it rewrites what it can prove — a
708
+ mistyped prop, a wrong relative path, a missing import — and then the gates
709
+ read the result. A typo is mechanical, and it should never reach you as work
710
+ to do.
711
+
712
+ ## The north metric
713
+
714
+ Every `flet-box verify` run appends a row to the project's log —
715
+ `.fletbox/metrics/generations.md` for a generated app, `metrics/generations.md`
716
+ for this repository — with the time, the project, whether the gates were green,
717
+ which gates failed and which codes they reported. **Every** run, green or not: a
718
+ log that keeps only the successes cannot tell a correction from a first try.
719
+
720
+ ```bash
721
+ flet-box metrics # the metric and the failures that recur
722
+ flet-box metrics --log <file> # read another log
723
+ ```
724
+
725
+ A **generation** is a run of failing rows closed by the first green one. The
726
+ **north metric** is the share of generations whose *first* run was green — the
727
+ share of code that passed the gate with no correction at all. It is the number
728
+ that moves when the code gets better, not when the report gets softer.
729
+
730
+ The same command prints the three failures that recur most often and the rule
731
+ each one should belong to, and it **exits non-zero** when a code has come back
732
+ three times with no rule behind it. That is the loop closing: a code that keeps
733
+ coming back is a rule that has not been written yet.
734
+
735
+ The log also holds a **Gate defects** table. A code written there with its
736
+ window — the first and the last day it explains — is the framework's debt, not
737
+ the project's correction: those runs are left out of the metric, never asked to
738
+ justify a rule, and printed on their own (`fixed`, or `⚠ OPEN`). A run after the
739
+ window's last day counts again, so an old row can never silence the same mistake
740
+ coming back. The table is data in the log, not a list inside the command: a
741
+ project records what it proved, and the next release cannot rewrite its past.
742
+
593
743
  ## Command reference
594
744
 
595
745
 
@@ -623,6 +773,21 @@ The full contract — the 21 rules, every finding code, and how to fix one — i
623
773
  | `flet-box check-ui` | Runs the clean-UI gate over `src/`: tokens, scale, tap targets, labels, contrast. |
624
774
  | `flet-box check-ui --tokens` | Prints the measured contrast of every color token, on the background and on the surface. |
625
775
  | `flet-box check-ui --strict` | Makes the contrast warnings fail the run, not just the errors. |
776
+ | `flet-box check-api` | Checks that every widget, prop and import your code names really exists. |
777
+ | `flet-box check-api --props <Widget>` | Prints the real props of one widget. |
778
+ | `flet-box check-api --list` | Prints every public export. |
779
+ | `flet-box check-api --emit-api` | Writes `.fletbox/api/cheatsheet.md`, the API an assistant reads first. |
780
+ | `flet-box unpack <Widget>` | Cross-checks a widget's four surfaces and labels what disagrees. |
781
+ | `flet-box unpack <Widget> --example` | Prints a paste-ready call built only from verified props. |
782
+ | `flet-box unpack <Widget> --diff` | Prints the reconciliation alone: declared vs real, and what disagrees. |
783
+ | `flet-box unpack --all` | Writes the whole verified surface to `.fletbox/api/api.json`. |
784
+ | `flet-box unpack --all --md` | Adds the readable `api.md` beside it. |
785
+ | `flet-box verify` | Runs every gate at once: one report, one exit code. |
786
+ | `flet-box verify --no-tests` | The static gates only, for a pipeline that runs the suites in their own jobs. |
787
+ | `flet-box verify --fix` | Runs the mechanical repair first, then the gates. |
788
+ | `flet-box metrics` | Reads the project's log: the north metric and the failures that recur. |
789
+ | `flet-box audit-fix` | Rewrites what it can prove: a broken import, a mistyped prop, a renamed prop. |
790
+ | `flet-box audit-fix --only migrations` | Applies only the renames from [the migration guide](../guides/migration.md). |
626
791
  | `flet-box pkg` | Opens the package manager. |
627
792
  | `flet-box --version` | Shows the CLI version. |
628
793
  | `flet-box --help` | Shows the command list. |
@@ -714,6 +879,7 @@ npm install --save-dev esbuild
714
879
  - Learn the basics in [Start here](../widget/START_HERE.md).
715
880
  - Learn complete app structures in [Build your first FletBox app](../guides/app-templates.md).
716
881
  - Explore every widget in the [widget documentation](../widget/README.md).
882
+ - Ask "where is the work?" with [the AI toolkit](../guides/ai-toolkit.md) — `flet-box report`, `flet-box tools`, `flet-box mcp`.
717
883
 
718
884
  ---
719
885
 
@@ -16,6 +16,12 @@ This directory is the **conceptual index** of FletBox: how to build apps, set up
16
16
  - **[Accessibility](accessibility.md)** — Chapter 13 · the focus ring, the
17
17
  keyboard pass over every press, the roles and states the widgets declare, and
18
18
  the overlays that hold the keyboard.
19
+ - **[Migrate an app to a newer FletBox](migration.md)** — Chapter 14 · what
20
+ changed between releases, the "de X a Y" table, and the codemod that writes
21
+ the new names for you.
22
+ - **[The AI toolkit](ai-toolkit.md)** — Chapter 15 · the map from a question to
23
+ the command (`flet-box tools`), the per-file diagnosis (`flet-box report`), and
24
+ the same tools over MCP stdio (`flet-box mcp`).
19
25
  - **[Widget structure](widget-structure.md)** — the canonical, modular shape every widget follows (and how new ones are added).
20
26
 
21
27
  ## Appendices (Advanced — for shipping)
@@ -158,6 +158,7 @@ is already in place; the table exists so you know what not to duplicate.
158
158
  | `Switch` | `switch` | `aria-checked` |
159
159
  | `Checkbox` | `checkbox` | `aria-checked` |
160
160
  | `Radio` / `Rating` | `radio` / `radiogroup` | `aria-checked` |
161
+ | `ThemePicker` | `radiogroup` / `radio` | `aria-checked`; one Tab stop per swatch, and Enter or Space picks |
161
162
  | `Slider` | `slider` | `aria-valuemin`, `aria-valuemax`, `aria-valuenow`, `aria-orientation` |
162
163
  | `ProgressBar`, `CircularBar` | `progressbar` | `aria-valuemin`, `aria-valuemax`, `aria-valuenow`, `aria-busy` while indeterminate |
163
164
  | `Dropdown` | `combobox` | `aria-expanded`, `aria-controls`, `aria-activedescendant`, `aria-invalid`, `aria-labelledby` |
@@ -276,7 +277,7 @@ forbids. The runtime half lives in `/tests/a11y.html`.
276
277
  ## Continue reading
277
278
 
278
279
  - **Previous:** [Clean UI](clean-ui.md) — Chapter 12
279
- - **Next:** [Minify and protect a FletBox build](minification-and-protection.md) — Appendix A
280
+ - **Next:** [Migrate an app to a newer FletBox](migration.md) — Chapter 14
280
281
  - **Index:** [Guides index](README.md) · [The FletBox Book](../README.md)
281
282
 
282
283
  You are reading **Chapter 13 · Accessibility**.
@@ -0,0 +1,166 @@
1
+ # The AI toolkit
2
+
3
+ A FletBox project ships with ten checkers, and each one is right about its own
4
+ slice: the API gate knows the prop is invented, the design gate knows the
5
+ spacing is off-scale, the type gate knows the editor is unhappy. What an
6
+ assistant lacks is not another checker — it is a **map from the question in front
7
+ of it to the command that answers it**, and one report that puts every answer on
8
+ the same page.
9
+
10
+ This chapter is that map. Three commands share one catalogue:
11
+
12
+ | Command | What it is for |
13
+ | --- | --- |
14
+ | `flet-box tools` | the map: every tool, the question it answers, the exact command |
15
+ | `flet-box report` | the diagnosis: every file of *this* project, its verdict, and what to do next |
16
+ | `flet-box mcp` | the same catalogue over MCP stdio, for an assistant with no shell |
17
+
18
+ All three are **read-only**. None of them edits a source, renames a prop, runs a
19
+ repair, builds or publishes. The single file they can produce is the report's
20
+ own HTML page, and only when `--html` asks for it.
21
+
22
+ ## The map: `flet-box tools`
23
+
24
+ ```bash
25
+ flet-box tools # the catalogue, printed as a map
26
+ flet-box tools --json # the same catalogue on stdout, for a script
27
+ flet-box tools --emit # write .fletbox/api/tools.json into the project
28
+ ```
29
+
30
+ Each entry carries the question in the words a person uses when they are stuck,
31
+ the command, its arguments, its output formats, whether it writes anything, and
32
+ the moments it applies. The nine tools are:
33
+
34
+ | id | Question it answers |
35
+ | --- | --- |
36
+ | `report` | Where is the work? Which file is wrong, how wrong, what is missing? |
37
+ | `widget_props` | Which props does this widget really accept, with types and deprecations? |
38
+ | `widget_contract` | Do declaration, engine and docs agree — and which props are dead? |
39
+ | `list_widgets` | What exists in this version of the framework? |
40
+ | `check` | Is any widget, prop or import invented? |
41
+ | `design` | Are the tokens, the scale, tap targets, labels and contrast legal? |
42
+ | `syntax` | Does every module parse? |
43
+ | `types` | What does the editor complain about? |
44
+ | `metrics` | Which mistakes keep coming back, and does a rule own each one? |
45
+
46
+ The catalogue is one file of pure data (`bin/utils/toolkit.js`). The CLI prints
47
+ it, the report links every finding back to the tool that proves it, and the MCP
48
+ server exposes the same entries — one source, three mouths. A tool that is
49
+ missing from that file does not exist for any of them, which is what keeps the
50
+ three from drifting apart.
51
+
52
+ ## The diagnosis: `flet-box report`
53
+
54
+ `flet-box verify` answers a yes/no question — *may I say this is done* — gate by
55
+ gate, because that is what an exit code needs. An assistant that is **lost**
56
+ needs the other reading of the same facts: not which gate failed, but which file
57
+ is wrong, how wrong, and which one thing to do next.
58
+
59
+ ```bash
60
+ flet-box report # text, in the terminal
61
+ flet-box report --json # the whole report as data
62
+ flet-box report --md # Markdown, to paste or commit
63
+ flet-box report --html # .fletbox/reports/report.html
64
+ flet-box report --html --out /tmp/report.html
65
+ flet-box report --tests # also run the project's own suites
66
+ ```
67
+
68
+ The command runs the six static gates once — `syntax`, `api`, `types`, `ui`,
69
+ `structure`, `surface` — and then **re-groups their findings by file**, because
70
+ the file is what the reader opens. Three decisions make it a tool rather than
71
+ another number:
72
+
73
+ 1. **Every file is named**, clean ones included, with its line count, its
74
+ verdict, and the widgets it imports. A report that lists only the failures
75
+ cannot tell "this file is fine" from "this file was not read".
76
+ 2. **Every finding carries a next step and a rule.** A code with no suggestion
77
+ is printed with the tool that proves it instead — "something is wrong
78
+ somewhere" is not a finding.
79
+ 3. **It writes no metrics row.** A diagnostic must not change the record it is
80
+ diagnosing; only `verify` owns
81
+ `.fletbox/metrics/generations.md`.
82
+
83
+ The text report reads in this order:
84
+
85
+ ```
86
+ 🩺 FletBox report · my-app · flet-box@1.1.2 · read-only
87
+
88
+ files: 12 clean · 0 with findings
89
+ 0 error(s), 0 warning(s) · 24 widgets, 0 with contract gaps
90
+
91
+ ✓ syntax clean
92
+ ✓ api clean
93
+ ✓ types clean
94
+ ✓ ui clean
95
+ ✓ structure clean
96
+ ✓ surface clean
97
+ ```
98
+
99
+ When something is wrong, a ranked **next** list follows, one line per finding:
100
+ the file at `line:column`, the code, the message, the fix, and the rule that
101
+ owns it. Then the files that are not clean (with their widgets), any findings
102
+ that name the installed package rather than your code — the framework's own
103
+ debt, kept separate on purpose — the widget contract ledger, and the metrics
104
+ line.
105
+
106
+ The HTML page carries the same report in one self-contained file: inline CSS,
107
+ no `<script>`, no network request. It opens offline, in any browser, and every
108
+ value is escaped, so a report about code is safe to open even when that code
109
+ contains markup.
110
+
111
+ The exit code is `1` when the report has errors, so `flet-box report` can stand
112
+ in for `flet-box verify` in a script that only needs the verdict.
113
+
114
+ ## The server: `flet-box mcp`
115
+
116
+ An assistant with no shell cannot run `flet-box report`. `flet-box mcp` serves
117
+ the same catalogue over MCP stdio — newline-delimited JSON-RPC 2.0 on stdin and
118
+ stdout — so the same nine tools are callable without a terminal:
119
+
120
+ ```bash
121
+ flet-box mcp
122
+ ```
123
+
124
+ It answers `initialize`, `ping`, `tools/list` and `tools/call`. Two request
125
+ lines are enough to see it work:
126
+
127
+ ```json
128
+ {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}
129
+ {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"report","arguments":{"root":"."}}}
130
+ ```
131
+
132
+ Every tool result is text (the same text the CLI prints), so an editor or an
133
+ agent reads exactly what a person would read. A missing required argument or a
134
+ directory that does not exist comes back as a result with `isError: true`; an
135
+ unknown tool name is a JSON-RPC error (`-32602`). Neither is a crash, and
136
+ neither can be mistaken for an answer. When stdin closes behind a slow request,
137
+ the server finishes it before exiting — a one-shot client gets its answer.
138
+
139
+ The server **never** calls the logging path: it runs the gates, not `verify`, so
140
+ asking a question through MCP cannot add a row to the metrics log either.
141
+
142
+ ## Where to plug it in
143
+
144
+ - In an app's `package.json`, keep the catalogue current next to the API files:
145
+ `flet-box tools --emit` beside `flet-box unpack --all --md`.
146
+ - Commit `.fletbox/api/tools.json`: it is the map an assistant reads when it
147
+ cannot run a command.
148
+ - Treat `.fletbox/reports/` as generated output — a page you open, not a file
149
+ you review. Recreate it with `flet-box report --html`.
150
+ - Register `flet-box mcp` as an MCP server if your editor supports one; the
151
+ project path is the only argument it needs.
152
+
153
+ The loop stays the one the other chapters teach: `flet-box report` to find the
154
+ work, the named command to understand it, `npm run verify` to prove the fix.
155
+ The toolkit only removes the guess about **which** command answers the question
156
+ you have.
157
+
158
+ ---
159
+
160
+ ## Continue reading
161
+
162
+ - **Previous:** [Migrate an app to a newer FletBox](migration.md) — Chapter 14
163
+ - **Next:** [Minify and protect a FletBox build](minification-and-protection.md) — Appendix A
164
+ - **Index:** [Guides index](README.md) · [The FletBox Book](../README.md)
165
+
166
+ You are reading **Chapter 15 · The AI toolkit**.
@@ -33,7 +33,7 @@ Private browsing, sandboxed iframes, and strict browser policies may disable som
33
33
 
34
34
  ### Node.js
35
35
 
36
- Node.js 18 or newer is required for the CLI and build tooling. FletBox widgets themselves are browser-oriented and should not be rendered directly in a Node process without a DOM environment.
36
+ Node.js 20.9 or newer is required for the CLI and build tooling — the floor `package.json` declares in `engines`. FletBox widgets themselves are browser-oriented and should not be rendered directly in a Node process without a DOM environment.
37
37
 
38
38
  ## Build targets
39
39
 
@@ -0,0 +1,92 @@
1
+ # Migrate an app to a newer FletBox
2
+
3
+ > **Level: Intermediate.** Read this page when a FletBox release renamed or removed something your app uses. It follows [Accessibility](accessibility.md) — Chapter 13 — in the book's reading path.
4
+
5
+ FletBox does not break your app on purpose. A prop that gets a better name keeps working under the old one, and the framework keeps both until the next major says otherwise. **But a name you keep writing is a name you keep paying for**: the old spelling disappears at the next major, and the app breaks then, on a machine that is not yours.
6
+
7
+ So this page exists for two moments:
8
+
9
+ - **You are upgrading.** The table below says, prop by prop, what changed and what to write instead.
10
+ - **You are publishing a major.** `flet-box release --major` refuses to publish a version that has no section here — a major is exactly the release where an app has to change something, so the guide has to exist before the release does.
11
+
12
+ ## The rule the framework follows
13
+
14
+ A rename in FletBox is always done in this order:
15
+
16
+ 1. The new name is declared and documented **first**.
17
+ 2. The old name keeps working, marked `@deprecated` in `src/index.d.ts`.
18
+ 3. The old name lands in `src/widget-factory/deprecations.js` — the one table the guide, the codemod and the contract test all read.
19
+ 4. The old name is listed in the table below, with the version that renamed it.
20
+ 5. The old name is removed in the next **major**, and that major's section says so.
21
+
22
+ Nothing here is a breaking change inside the 1.x line. Read the table as a list of names to stop writing, not as a list of things that already broke.
23
+
24
+ ## 1.2.0
25
+
26
+ Every old name below still works in 1.2.0. Write the new one.
27
+
28
+ | Widget | From | To | What changed |
29
+ | --- | --- | --- | --- |
30
+ | `Accordion` | `onToggle` | `onPress` | The callback still receives the new expanded state; the name is now the framework-wide one. |
31
+ | `Checkbox` | `onCheck` | `onPress` | The callback still receives the new checked state. |
32
+ | `Dropdown` | `onChange` | `onPress` | The callback still receives the chosen value — and only the value. The second argument the old type promised was never sent. |
33
+ | `Radio` | `onSelect` | `onPress` | The callback still receives the new selected state. |
34
+ | `Slider` | `onChanged` | `onPress` | The callback still receives the new number. |
35
+ | `Switch` | `onToggle` | `onPress` | The callback still receives the new toggled state. |
36
+ | `Tooltip` | `tooltipDelay` | `delay` | Same number, same units: milliseconds. |
37
+ | `Scaffold` | `navSideBar` | `leftNavBar` | The side moved into the name. A call that also says `navSideBarPosition: "right"` becomes `rightNavBar`. |
38
+ | `Scaffold` | `navSideBarWidth` | `leftNavBarWidth` | The old width was accepted and then **ignored** — the panel kept the default width. The new name applies, so the panel finally takes the width you wrote. |
39
+ | `Scaffold` | `navSideBarPosition` | (removed) | The side now lives in the prop name (`leftNavBar` / `rightNavBar`). Nothing reads this prop any more, so the key goes with it. |
40
+
41
+ Two names that look like the ones above are **not** deprecated: `TreeView` still calls its own selection callback `onSelect` and its own expansion callback `onToggle`, because that is what a tree calls them. The rename was about the framework-wide `onPress`, and a tree's own vocabulary is not a candidate for it. `flet-box audit-fix` knows the difference: the table names a widget, not a spelling.
42
+
43
+ ## Applying the table
44
+
45
+ The framework ships a codemod for the rows where the answer is mechanical:
46
+
47
+ ```bash
48
+ npx flet-box audit-fix --only migrations
49
+ ```
50
+
51
+ In a project made with `flet-box create` the same command is `npm run fix` (which also repairs imports and mistyped props). The codemod rewrites only the calls it can prove:
52
+
53
+ - the widget has to declare **both** the old name and the new one;
54
+ - the call must not already carry the new name — two callbacks for one event is a decision, not a rename;
55
+ - for `Scaffold`, the call must not already carry a new sidebar prop, because the legacy one is inert there.
56
+
57
+ Anything it cannot prove is printed under **"Left for you to decide"** and left untouched. A codemod that guesses is worse than one that stops: a wrong rename changes the screen silently, and the gate would no longer complain about it.
58
+
59
+ What the codemod will **not** do, on purpose:
60
+
61
+ - it will not change a callback's *signature* — `Dropdown`'s old `onChange(value, label)` promised a second argument that was never sent, and the codemod renames the prop without inventing the argument;
62
+ - it will not touch a call that spreads another object (`{ ...props }`), because the keys inside are not visible;
63
+ - it will not rename anything that is not a FletBox widget call;
64
+ - it will not edit `docs/`, `skills/` or the framework's own sources.
65
+
66
+ Run it, then read the diff:
67
+
68
+ ```bash
69
+ npx flet-box audit-fix --only migrations
70
+ git diff
71
+ ```
72
+
73
+ ## Before you publish a major
74
+
75
+ A major release is the one that removes the old names for good. The framework will not let it through without this page saying what it removes:
76
+
77
+ ```bash
78
+ flet-box release --major
79
+ # ❌ the migration guide has no "## 2.0.0" section
80
+ ```
81
+
82
+ To publish it, add the section here first — one row per removed or renamed prop, with the version as the heading — and the release goes through. The rows are read by `scripts/check-migrations.mjs`, which also proves that the table above, the deprecated markers in `src/index.d.ts`, the deprecation table in the framework and this codemod all name the same things. A prop that is deprecated in the types but missing from this page fails CI, not the user's app.
83
+
84
+ ---
85
+
86
+ ## Continue reading
87
+
88
+ - **Previous:** [Accessibility](accessibility.md) — Chapter 13
89
+ - **Next:** [The AI toolkit](ai-toolkit.md) — Chapter 15
90
+ - **Index:** [Guides index](README.md) · [The FletBox Book](../README.md)
91
+
92
+ You are reading **Chapter 14 · Migrating to a newer FletBox**.
@@ -255,6 +255,7 @@ Minification reduces the web payload inside the native application. It does not
255
255
 
256
256
  ## Continue reading
257
257
 
258
- - **Previous:** [Accessibility](accessibility.md) — Chapter 13
258
+ - **Previous:** [The AI toolkit](ai-toolkit.md) — Chapter 15
259
259
  - **Next:** [Build FletBox for mobile and other platforms](mobile-and-platforms.md) — Appendix B
260
+ - **See also:** [Migrate an app to a newer FletBox](migration.md) — Chapter 14
260
261
  - **Index:** [Guides index](README.md) · [The FletBox Book](../README.md)
@@ -26,7 +26,7 @@ Capacitor packages the compiled web application inside a native shell. You can a
26
26
 
27
27
  ### For every platform
28
28
 
29
- - Node.js 18 or newer.
29
+ - Node.js 20.9 or newer (the CLI's `engines` floor).
30
30
  - npm.
31
31
  - A working FletBox project.
32
32
  - A production build that creates the directory configured as Capacitor's `webDir`.
@@ -212,6 +212,8 @@ Declare those files in `fletbox.config.json` and they become part of every relea
212
212
 
213
213
  Globs are relative to the project root and support `**`, `*` and `?`. At build time `flet-box createBundle` copies each match into `www/` at the same path, hashes it, and lists it in the manifest's `assets` array — which is also what your CI publishes to GitHub Pages.
214
214
 
215
+ A project created by `flet-box create` already declares its own pictures. The scaffold creates `assets/` and puts `assets/logo.png` there, so that folder is where an app keeps its images; the generated `fletbox.config.json` lists `assets/**/*.png`, `.jpg`, `.jpeg`, `.svg` and `.webp`. Without that entry the bundle copied `src/assets` (icons and fonts) and nothing else: the built app served every screen with a broken picture while `npm run dev` — which serves the project root — looked perfect. Other formats, or a file kept outside `assets/`, still need their own glob; a source document parked in `assets/` (the PDF a catalogue was written from) is deliberately not matched.
216
+
215
217
  The app then reads them through the loader instead of `fetch`:
216
218
 
217
219
  ```js
@@ -99,7 +99,7 @@ Queues also require Redis to coordinate jobs between workers.
99
99
 
100
100
  ## Production checklist
101
101
 
102
- - Use Node.js 18 or newer.
102
+ - Use Node.js 22 or newer — the floor `flet-box-server` declares in `engines` (the FletBox CLI itself needs 20.9).
103
103
  - Run `npm ci --omit=dev` in deployment.
104
104
  - Set a strong `JWT_SECRET`.
105
105
  - Remove hardcoded admin credentials.
@@ -18,7 +18,7 @@ import { border, margin, padding, gradient, shadow, color } from "flet-box";
18
18
  | Function | Signature | Returns | Description |
19
19
  | --- | --- | --- | --- |
20
20
  | `animation` | `animation(name, duration?, timing?, iteration?)` | `string` | CSS `animation` shorthand. `name` can also be an options object (`{ name, duration, timing, delay, iteration, direction, fillMode }`). |
21
- | `border` | `border(width = 1, style = "solid", color?)` | `string` | CSS `border` shorthand, e.g. `1px solid #e2e8f0`. |
21
+ | `border` | `border(width = 1, style = "solid", color)` | `string` | CSS `border` shorthand, e.g. `1px solid #e2e8f0`. The colour is required: a border without one is invisible. |
22
22
  | `gradient` | `gradient(type, colors, angle = 135)` | `string` | A CSS gradient background. `type` is `"linear"`, `"circle"` (radial), or `"conic"`; `colors` is an array of color strings. |
23
23
  | `margin` / `padding` | `margin(value)` / `padding(value)` | `string` | Spacing CSS. `value` can be a number, a string, or `{ all, horizontal, vertical, top, right, bottom, left }`. |
24
24
  | `rgba` | `rgba(r, g, b, a = 1)` | `string` | `rgba(r, g, b, a)` with an alpha default of `1`. |
@@ -29,7 +29,7 @@ import { border, margin, padding, gradient, shadow, color } from "flet-box";
29
29
  | `flex` | `flex(grow, shrink = 1, basis = "0%")` | `string` | CSS `flex` shorthand. `grow` can also be `{ grow, shrink, basis }`. |
30
30
  | `grid` | `grid(options)` | `string` | CSS grid template from `{ columns, rows, gap }`; `gap` can be a number or `{ row, column }`. |
31
31
  | `color` | `color(value)` | Color object | A mutable, chainable color. See the Color object below. |
32
- | `stackPosition` | `stackPosition(widget, props)` | `Widget` | Applies absolute positioning/centering to a widget and returns it. |
32
+ | `stackPosition` | `stackPosition(widget, props)` | `Widget` | Anchors a widget absolutely over its positioned ancestor and returns it. Takes `top`/`right`/`bottom`/`left` (numbers go through the `rem` contract), the logical `start`/`end`, and the shorthands `centerX`, `centerY`, `center`, `fullWidth`, `fullHeight`, `full`. A `false` value means "do not apply". |
33
33
  | `toREM` / `toPX` | `toREM(value)` / `toPX(value)` | `string \| undefined` | Convert a value between `rem` and `px`. |
34
34
  | `setBaseFontSize` | `setBaseFontSize(px)` | `void` | Change the `rem` base (default `16`). |
35
35
  | `getBaseFontSize` | `getBaseFontSize()` | `number` | The current `rem` base. |