bitwrench 2.0.32 → 2.1.1

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 (126) hide show
  1. package/README.md +211 -125
  2. package/dist/bitwrench-bccl.cjs.js +349 -188
  3. package/dist/bitwrench-bccl.cjs.min.js +2 -39
  4. package/dist/bitwrench-bccl.cjs.min.js.gz +0 -0
  5. package/dist/bitwrench-bccl.esm.js +349 -188
  6. package/dist/bitwrench-bccl.esm.min.js +2 -39
  7. package/dist/bitwrench-bccl.esm.min.js.gz +0 -0
  8. package/dist/bitwrench-bccl.umd.js +349 -188
  9. package/dist/bitwrench-bccl.umd.min.js +2 -39
  10. package/dist/bitwrench-bccl.umd.min.js.gz +0 -0
  11. package/dist/bitwrench-code-edit.cjs.js +17 -6
  12. package/dist/bitwrench-code-edit.cjs.min.js +2 -20
  13. package/dist/bitwrench-code-edit.es5.js +8 -3
  14. package/dist/bitwrench-code-edit.es5.min.js +2 -19
  15. package/dist/bitwrench-code-edit.esm.js +17 -6
  16. package/dist/bitwrench-code-edit.esm.min.js +2 -19
  17. package/dist/bitwrench-code-edit.umd.js +17 -6
  18. package/dist/bitwrench-code-edit.umd.min.js +2 -19
  19. package/dist/bitwrench-code-edit.umd.min.js.gz +0 -0
  20. package/dist/bitwrench-debug.js +1 -1
  21. package/dist/bitwrench-debug.min.js +1 -1
  22. package/dist/bitwrench-lean.cjs.js +2492 -1628
  23. package/dist/bitwrench-lean.cjs.min.js +2 -80
  24. package/dist/bitwrench-lean.cjs.min.js.gz +0 -0
  25. package/dist/bitwrench-lean.es5.js +2740 -1838
  26. package/dist/bitwrench-lean.es5.min.js +2 -49
  27. package/dist/bitwrench-lean.es5.min.js.gz +0 -0
  28. package/dist/bitwrench-lean.esm.js +2492 -1628
  29. package/dist/bitwrench-lean.esm.min.js +2 -80
  30. package/dist/bitwrench-lean.esm.min.js.gz +0 -0
  31. package/dist/bitwrench-lean.umd.js +2492 -1628
  32. package/dist/bitwrench-lean.umd.min.js +2 -80
  33. package/dist/bitwrench-lean.umd.min.js.gz +0 -0
  34. package/dist/bitwrench-util-color.cjs.js +251 -0
  35. package/dist/bitwrench-util-color.cjs.min.js +3 -0
  36. package/dist/bitwrench-util-color.es5.js +256 -0
  37. package/dist/bitwrench-util-color.es5.min.js +3 -0
  38. package/dist/bitwrench-util-color.esm.js +241 -0
  39. package/dist/bitwrench-util-color.esm.min.js +3 -0
  40. package/dist/bitwrench-util-color.umd.js +257 -0
  41. package/dist/bitwrench-util-color.umd.min.js +3 -0
  42. package/dist/bitwrench-util-css.cjs.js +2 -1
  43. package/dist/bitwrench-util-css.cjs.min.js +2 -21
  44. package/dist/bitwrench-util-css.es5.js +2 -1
  45. package/dist/bitwrench-util-css.es5.min.js +2 -20
  46. package/dist/bitwrench-util-css.esm.js +2 -1
  47. package/dist/bitwrench-util-css.esm.min.js +1 -19
  48. package/dist/bitwrench-util-css.umd.js +2 -1
  49. package/dist/bitwrench-util-css.umd.min.js +2 -20
  50. package/dist/bitwrench-util-css.umd.min.js.gz +0 -0
  51. package/dist/bitwrench.cjs.js +2826 -1801
  52. package/dist/bitwrench.cjs.min.js +2 -99
  53. package/dist/bitwrench.cjs.min.js.gz +0 -0
  54. package/dist/bitwrench.css +403 -479
  55. package/dist/bitwrench.d.ts +70 -73
  56. package/dist/bitwrench.es5.js +3106 -2020
  57. package/dist/bitwrench.es5.min.js +2 -67
  58. package/dist/bitwrench.es5.min.js.gz +0 -0
  59. package/dist/bitwrench.esm.js +2826 -1801
  60. package/dist/bitwrench.esm.min.js +2 -99
  61. package/dist/bitwrench.esm.min.js.gz +0 -0
  62. package/dist/bitwrench.min.css +1 -1
  63. package/dist/bitwrench.umd.js +2826 -1801
  64. package/dist/bitwrench.umd.min.js +2 -99
  65. package/dist/bitwrench.umd.min.js.gz +0 -0
  66. package/dist/builds.json +222 -134
  67. package/dist/bwserve.cjs.js +289 -282
  68. package/dist/bwserve.d.ts +157 -0
  69. package/dist/bwserve.esm.js +290 -283
  70. package/dist/sri.json +54 -46
  71. package/docs/README.md +6 -3
  72. package/docs/app-patterns.md +7 -6
  73. package/docs/bitwrench-for-wasm.md +53 -54
  74. package/docs/bitwrench-mcp.md +2 -2
  75. package/docs/bitwrench-northstar-principles.md +406 -0
  76. package/docs/bitwrench-taco-schema-discussion.md +2 -2
  77. package/docs/bitwrench_api.md +191 -106
  78. package/docs/bitwrench_typescript_usage.md +5 -5
  79. package/docs/bw-attach.md +29 -75
  80. package/docs/bwserve.md +200 -168
  81. package/docs/cli.md +36 -12
  82. package/docs/component-cheatsheet.md +2 -2
  83. package/docs/component-library.md +4 -4
  84. package/docs/component-lifecycle.md +234 -0
  85. package/docs/drift-lint.md +268 -0
  86. package/docs/framework-translation-table.md +4 -4
  87. package/docs/llm-bitwrench-guide.md +60 -50
  88. package/docs/routing.md +11 -13
  89. package/docs/state-management.md +110 -109
  90. package/docs/taco-format.md +13 -14
  91. package/docs/theming.md +13 -3
  92. package/docs/thinking-in-bitwrench.md +858 -983
  93. package/docs/tutorial-bwserve.md +37 -36
  94. package/docs/tutorial-embedded.md +10 -21
  95. package/docs/tutorial-website.md +2 -2
  96. package/package.json +38 -7
  97. package/readme.html +262 -161
  98. package/src/bitwrench-bccl-entry.js +2 -2
  99. package/src/bitwrench-bccl.js +346 -185
  100. package/src/bitwrench-code-edit.js +16 -5
  101. package/src/bitwrench-color-utils.js +117 -181
  102. package/src/bitwrench-file-ops.js +2 -2
  103. package/src/bitwrench-lean.js +4 -3
  104. package/src/bitwrench-router.js +5 -2
  105. package/src/bitwrench-styles.js +420 -504
  106. package/src/bitwrench-util-color.js +240 -0
  107. package/src/bitwrench-util-css.js +1 -0
  108. package/src/bitwrench-utils.js +4 -0
  109. package/src/bitwrench.d.ts +70 -73
  110. package/src/bitwrench.h +5 -0
  111. package/src/bitwrench.js +1939 -933
  112. package/src/bwserve/attach.js +0 -1
  113. package/src/bwserve/bwclient.js +172 -32
  114. package/src/bwserve/bwshell.js +0 -4
  115. package/src/bwserve/client.js +59 -220
  116. package/src/bwserve/index.js +59 -26
  117. package/src/bwserve.d.ts +157 -0
  118. package/src/bwserve.h +5 -0
  119. package/src/cli/attach.js +12 -75
  120. package/src/cli/convert.js +2 -2
  121. package/src/cli/serve.js +37 -35
  122. package/src/generate-css.js +1 -1
  123. package/src/mcp/knowledge.js +4 -4
  124. package/src/mcp/live.js +21 -13
  125. package/src/mcp/tools.js +0 -1
  126. package/src/version.js +3 -7
package/dist/sri.json CHANGED
@@ -1,51 +1,59 @@
1
1
  {
2
- "version": "2.0.32",
2
+ "version": "2.1.1",
3
3
  "algorithm": "sha384",
4
- "generated": "2026-04-26",
4
+ "generated": "2026-07-15",
5
5
  "files": {
6
- "bitwrench-bccl.cjs.js": "sha384-fm4zFar3/KSZQOnu2NcQvL2DYUPEF8/tUB9l41gvlGmck5X/5uTYFu2kNgaaA26q",
7
- "bitwrench-bccl.cjs.min.js": "sha384-fEsank/EtCyR68QbgEUtH1psd1nkBb1VJLk45BEhEXPFls1toRUC2lZycYiy5hFc",
8
- "bitwrench-bccl.esm.js": "sha384-wecVxRuSlMVtxfXy6SpvV3hXu8k7y/DISzM1E5IzaPTR2dBYDtYviHE97ozP2jv4",
9
- "bitwrench-bccl.esm.min.js": "sha384-RSXcqzdjCGFG0F8Epk46vtkbNlmgakdbHq173zwsDJTHiQFEtrUbnzAeX7Pnl5l9",
10
- "bitwrench-bccl.umd.js": "sha384-nS5TE4XMDoKVmCt8+yEwpZu18i2+V6QzT4nhOcLNIHtT+aE5oENbmzjvKHPgKpeu",
11
- "bitwrench-bccl.umd.min.js": "sha384-N0MQ5cBPBi5gPbXEkbj9lj2fIS+HYJ9V/LJAdKJiCjK33Bo0/zseH46vXHhAIZTf",
12
- "bitwrench-code-edit.cjs.js": "sha384-tuXJYkD/sqwV1GCmIuoP2o75V8XNZRCRqBKhCjYmUgg3QuZ3ZBtpPo23WjyddJvA",
13
- "bitwrench-code-edit.cjs.min.js": "sha384-ngqdXykvURrYAUvEzwhZVdw8oSj7FOnL0qFY0JulD7aSAlfn5JFPZOHTXl0NhIK0",
14
- "bitwrench-code-edit.es5.js": "sha384-XeXDSvblUT6/54AfgvVZvtGAeGz+cdxveRu/Aq1XXfPL0HgzkpnV09BnCVLXIiLW",
15
- "bitwrench-code-edit.es5.min.js": "sha384-Tqju598rz/V9wjuUXb5RhUUPHI6eTE0JlUVUZM9DlIEQHmLCfGgaRRMyJfXQpsP9",
16
- "bitwrench-code-edit.esm.js": "sha384-mtq5V7Ui3KGDryxGWU4Jqkj1r/L+U0nNXzbkp5QphkV0c8PHfrguQ0IvVVZkhwKu",
17
- "bitwrench-code-edit.esm.min.js": "sha384-EZ8Uy2kOeTJivj9bSjXXIGiVHkoe5oVXGbsbf/1LxvuBz2WyyJnFo96Xcn8kYD7O",
18
- "bitwrench-code-edit.umd.js": "sha384-9BonoA/PJugxXVfIKr8l/kihj7KvJI6xshuH42U66A9Az7rbVAZQ4s2JZnI6Gbrm",
19
- "bitwrench-code-edit.umd.min.js": "sha384-1D3g7bae01at7MMizZlahUD5IHbNXzozrtePL8CPNa+UOAQeIhSpmCMW1lntGztu",
20
- "bitwrench-debug.js": "sha384-5EkF/Cef5HDCw+yQ/AGJRDzMLFjwoJkdTByXC/o0Zsw/ap0ZT1Yc4Wr+sQCz1m6U",
21
- "bitwrench-debug.min.js": "sha384-ZQPh4z4LD6ykxD5hCn9E4hUnyn35ZXa4FtF/dg8m93J/jmpG5VZNqNT6u5Y7sA6P",
22
- "bitwrench-lean.cjs.js": "sha384-iDCwAaIs4NebdLE9S9S/GNNIMkWVAh00klHSVsdAX1gL0Y76xKw/tDX2lAjpbWO+",
23
- "bitwrench-lean.cjs.min.js": "sha384-xZA3ZXEFVXHs6jrAtjUdJToCThXA6hj8zP247vn044FQBJ9ngNTIX14nUm1DK9A/",
24
- "bitwrench-lean.es5.js": "sha384-75O3mZrFRf7n5d7DwrTMhxDL5DewH6uly/jvwahUF1dToVYtG2Iu3s/eofkHf0Pr",
25
- "bitwrench-lean.es5.min.js": "sha384-Dai/3Rb6qXYvLirAwePAXrRnejdXm2xmupf0NbnyEYphkHPLL6J7dAQjWasCopHt",
26
- "bitwrench-lean.esm.js": "sha384-SocmGevK+OW6CQqdahu4Qsg5+9c0DAsHwL9k9Y+zTvbjJSLF6CJeRnMJb7o5nkK7",
27
- "bitwrench-lean.esm.min.js": "sha384-e6uhgikkdh1x/MOKiTD1mTYZ7tTU4NUJl0HCljYsnLP3yN+uTNx93ekhxmbYgfDh",
28
- "bitwrench-lean.umd.js": "sha384-sOypmarFMiIbl+sC0CJusIUdUFN/j2WogkGvmGhoB8yC7XoBe/DKajRkF8RiWibi",
29
- "bitwrench-lean.umd.min.js": "sha384-CTMjnWZhncKenL6e7Vk0wvNELUPkHqHl3YlvspR0n+7OParJqIEkPt1tGXhChMPy",
30
- "bitwrench-util-css.cjs.js": "sha384-gerlRoXtra87zahLjt228sBeSPL2+nYGoLveS379diioI7MgwN1mTVuMb5RK1xaf",
31
- "bitwrench-util-css.cjs.min.js": "sha384-C1zpPjlUL/R1xnIybV90VTNYl/F6j6F3TaPcPns7zfmkg+Xun+AkF5NKVRTlD1Cj",
32
- "bitwrench-util-css.es5.js": "sha384-MDazdsxvfVUMjTQ/recckKIwTyefUEW/UKAvEgaqyW9Frj7R2WjiiHn4Ikjz9M22",
33
- "bitwrench-util-css.es5.min.js": "sha384-coYGdR9MP/ldzY3/j+FQTb9UxbYNk2K806voG8PY5tHG9RU1bnrZqa6FouV7trD9",
34
- "bitwrench-util-css.esm.js": "sha384-1yE/wlyGSSIu2yMlxdSHeA5U+0XNt50kqrCdOnUp5ph88tHMUv3MwxoBnetc2gCZ",
35
- "bitwrench-util-css.esm.min.js": "sha384-tRB0z5KnuxWkkPq+qW7gJj2+SuOlXkc6hH3ip962GZsQGjgc4P9SsQTIed1IWbpw",
36
- "bitwrench-util-css.umd.js": "sha384-HbFyByrgtpsOVL3lvZtse8fAqsQqLbU4Ow+Z7oEA+AiKHGxZaDuF+rznFH0J30+3",
37
- "bitwrench-util-css.umd.min.js": "sha384-8UAqTLqrCHVr8s5/OS1qTp6DDskm/RxvBZ0xhsf12c9LIeuF7kMr8ZIXqN79scpk",
38
- "bitwrench.cjs.js": "sha384-Ci2BIUNMP9Q7wl2w6+0HMO3eQL5AyMQl9YLAEEmB/Ja9c+RTMFlg+EZ1vbqJ1DOf",
39
- "bitwrench.cjs.min.js": "sha384-B//xIia0t3lGcAU7c28ne9RSpov2OuOmAXynlmG5MR5gQUBejnTUhqAy36+ya51n",
40
- "bitwrench.css": "sha384-SDv/NXaJpEnyfH1/lwbUjgUZXRrNM7JJrhkQeSIQrbr0bfp4UO3TaWI4OXCW1wYb",
41
- "bitwrench.es5.js": "sha384-rQfMtRZJF51qE/N7OqBUYXUqgyROYNxsVUyZdc9/M6KH+IsSpafZvIDB86tExKV5",
42
- "bitwrench.es5.min.js": "sha384-Y75wnUbt8MWe2v0SoVXWoQ84zVpMcaw6yOMdEjKLNuA4xQvrpxAHwz1zR3Cfd9rS",
43
- "bitwrench.esm.js": "sha384-D62HkkwghT7OrRZf4ndEwdzmCJIJbWjuHoy2RLqDG0Edaoz2tJkJk5ZvbNK+Lm76",
44
- "bitwrench.esm.min.js": "sha384-rSqI2lgJzv/V5Ij1jypuTU/AeQ8ba1NbM84tLMrP/wCEJnCiCrfNAOEagt2sSXB8",
45
- "bitwrench.min.css": "sha384-4ymUTaU2kwrsPLCsEGReVJe2rGzsHkNG1BjrHB7EGAOqMK+SgRvaHPoYUFk7tXSE",
46
- "bitwrench.umd.js": "sha384-uuSgbN2ItPiqasHNeGd3B99n0NWG0bvmLJHtGlUX+BxAAyPf7fV1V5Sr1Cpaac5v",
47
- "bitwrench.umd.min.js": "sha384-lt/nabWEOxYufCHBZYnYPi6i2tKQLauBh/+1/QuMN9PCaXCzd5Ejrtw9TvBoixrO",
48
- "bwserve.cjs.js": "sha384-mcUPopJ35fxJOI6/ctgHdC7BjQzpxgY4Omyr+KQRxbu0YX6f9o/A65oOwuG0VXjP",
49
- "bwserve.esm.js": "sha384-bacd5UtYAlD1EbFny1eDfFF8Jg8Vr67TtyhMALN5rWdAMu9ubGOBVH+Z4RGxkiM/"
6
+ "bitwrench-bccl.cjs.js": "sha384-B0aQIxXhxcyrAlix+j4UC8K7oKG/dVwC0Oe1/wmqTEdn8b1KIfnl3b0uumIEguGc",
7
+ "bitwrench-bccl.cjs.min.js": "sha384-oE3RnWAqbgoD3hV8KMScq3IYNj8lhl5aqBgbPwqnSN18NygVuXxYgt4JgJ/P3a3a",
8
+ "bitwrench-bccl.esm.js": "sha384-Y4N70nFgy6szh6GDz5WakwlcFe1YdB0pm9qmhDT0vFgvEYK/AXtMeCkbRFZa4bKS",
9
+ "bitwrench-bccl.esm.min.js": "sha384-/u3kujGMJ2CgT0EiXEg3rs1PjIODUu0uP0pqxBpD9bjkFcgmd9uS/N3RpZ/Kl9eO",
10
+ "bitwrench-bccl.umd.js": "sha384-LwgwBffGNjOgw98QUogo1mvT+KIRkgfDchIBxm3cpObrFat8qXdw9vhk1fcLrYvd",
11
+ "bitwrench-bccl.umd.min.js": "sha384-RkYOxXKlcnZvfR1cqPK6dlszvtyIhJ0u4SKnjgdV7YmTmvEexVVrcHiYT+ZTJZ4o",
12
+ "bitwrench-code-edit.cjs.js": "sha384-5xtpD4Hdaxr2qBRbhFgwtBTPWQ9UGh1Vb9drHKMNmTs/HYYnEByhz+nf/Okv9ILi",
13
+ "bitwrench-code-edit.cjs.min.js": "sha384-jdom5FXkU52Y2dEZY+T6nghl403ARZDzJN5mrlwfcO88xTm3HIHohhb1GUfXV2py",
14
+ "bitwrench-code-edit.es5.js": "sha384-lZWGCR5cf7mDhoK1P+ZC8XdU7PBtg+ATnZ3FLCBqV1U8pi5KowozoXaUqlw5jHdb",
15
+ "bitwrench-code-edit.es5.min.js": "sha384-56hIGJN49aKfPphqK3jlHfLWiCk71nVTj3q82P3EOcmzvIS1ECGlD9e5CtaTCIIm",
16
+ "bitwrench-code-edit.esm.js": "sha384-MRKH7iiNKgtAA+QJPYppQpvIXnT8iU5jeD5+pOmcz9D9YC2UAMwNvi+tEmAKlD7S",
17
+ "bitwrench-code-edit.esm.min.js": "sha384-Oj5ZgB9aeUmKMGq4h+MqCvFpw6pyOTzzTaJXEZRQX1Z768fz8cweyjV68Fqtx9Xm",
18
+ "bitwrench-code-edit.umd.js": "sha384-JndphcsfDanAFd5WDfxm4Po/Y9Pe9iNoY4Bwiu2VcSHge1oWHkdCLxD9Q7IIy2U4",
19
+ "bitwrench-code-edit.umd.min.js": "sha384-R1LGH2VGWZFcnWN+HXrrGbJUUQOVvkoooeh9AqFyCbDVUBtbu/pSd2kbR/BMtFGW",
20
+ "bitwrench-debug.js": "sha384-tMsS8YNpnWx+t4DEZX6JoSoYFHA7SjlnjPROmOMQVn/CVFtQWl5yL66pF+bNLh/6",
21
+ "bitwrench-debug.min.js": "sha384-ClXhaom0UNWzEzMbq3oaahMjO87BNjFu+7rLEI/FRG7DZLtp2vzr2dINQXGEsuCz",
22
+ "bitwrench-lean.cjs.js": "sha384-cqGEqf6HhVCj042PoSCRWhcQdOkMN4livX/HwK8ChVHX6ub0WnWdKhcvvrajSabf",
23
+ "bitwrench-lean.cjs.min.js": "sha384-B7kFM0sE9tmkYGprcwG2j9/fy4j4RtsaTnXiulO0gY6dBm8GoEfniTITKNeVir60",
24
+ "bitwrench-lean.es5.js": "sha384-sN/rWICehichsCcBxMUwA2Crkuz4JcIu2hOIByXnNktG5dzeiwJTtHzcIo2GDFBe",
25
+ "bitwrench-lean.es5.min.js": "sha384-cupxyMkbBM35mP97l7v+65Pu9g1QxP6J7Hlh+7EsOsE+s0sJxuY4tnHD3zqs76GL",
26
+ "bitwrench-lean.esm.js": "sha384-meRyTgeHW04mZOTyWwHAo+PBgs2zYSQuxurJWUWBhNXRU7HHbmMT/d4aCo/ALWHj",
27
+ "bitwrench-lean.esm.min.js": "sha384-LIPDtrKXNP1FBwNwqyQWeLCJlvWkVbJDIsGqZqlVxwsGhidq64phTwKoXFrRv+Ad",
28
+ "bitwrench-lean.umd.js": "sha384-o6YpWpqHVxfqHlJ6snSDb9TgdynZoIfgG0C3+iaI1joZGe6JJGTkMkN5tEc1yGpH",
29
+ "bitwrench-lean.umd.min.js": "sha384-sZQ7rNCvzu6db3bFonVOkZRn3jQiIfSPBYh5nqrnZwf5sNYKiX4y/HCUg3uqXPPC",
30
+ "bitwrench-util-color.cjs.js": "sha384-xhNNGd3AcHdh93qURLsapQVDhkjvARGUCc7nyJ0w22g8exk48hQJaYkCaIz+D/to",
31
+ "bitwrench-util-color.cjs.min.js": "sha384-wV0yhsO7QMkeQ39yAacwRzaSJOELAbwKaYLyFUTSL94VBoNK1J5hcaK4kglabtdw",
32
+ "bitwrench-util-color.es5.js": "sha384-vr/EQBigtmIOxwXzEGmqUiMlMgGR7AlQySEgWuTFzW4X+0o1rAHBJb6+4J2BxrTN",
33
+ "bitwrench-util-color.es5.min.js": "sha384-jGAyJ7VONHCW5Mg002ehyDR9/7L84j5iDWj6HVXUTO1KZEUokY5pLAJgVP8Zd31u",
34
+ "bitwrench-util-color.esm.js": "sha384-veGQ0Sdn5YSUIGlcvJA5FCgzL5aRxLjYcNtWa1qe/8gJ0mg+AQrn4QRi9Ik2gLwG",
35
+ "bitwrench-util-color.esm.min.js": "sha384-z83iY/YxP+Vy4rh8b42lnI5VUcrRrypFEUnT0gfHLlqKZ0ecqa+liQfgTAjXR+c/",
36
+ "bitwrench-util-color.umd.js": "sha384-YIIeopsm4OKn6AIEelm10wEKsdQY4HRAzMT/QmYOg+j4BSHurT4mdClUGNpFgwPb",
37
+ "bitwrench-util-color.umd.min.js": "sha384-XTVxvWBmjZdZa+2jZPTqwTimVCahhHkUoe/7ek3P/v2dHhNqaIKlqDbctEJ38+u+",
38
+ "bitwrench-util-css.cjs.js": "sha384-JqkhxHMrnFcB2UvZp3XzO5d7V/6DJK8HYhAdMWIIcgHioKVbE6L4O8viVymCXwj8",
39
+ "bitwrench-util-css.cjs.min.js": "sha384-r35+UKdAKgJizYYRebm5g+7RVlNTSAbO9ikhRY1Nc7Kelc3JlZPJI1V0IYJWm51q",
40
+ "bitwrench-util-css.es5.js": "sha384-4camXftDKDboxTqDSi5sMCAIBLu1UbpsPYjxAYR9GghuY+iRAFJaq7En5OaQPyVM",
41
+ "bitwrench-util-css.es5.min.js": "sha384-qQ9eOtZu7mSAa2ItOPnHDk0M2En44Et9Rd7ndoNz1eFHNf7jqlEtBHBYw05ld/8E",
42
+ "bitwrench-util-css.esm.js": "sha384-m0Ws+mQPHrcrTo2xvfpAGbPrzECuGtcfU5VwpgtuVmgP/7v5/FEVIolWGEwL1XKe",
43
+ "bitwrench-util-css.esm.min.js": "sha384-J3h0/oEd2/KZOFT94+v34E/NEOUhzgk7tnNazCOguUYdz1zTJFxIC3tefejDW9Li",
44
+ "bitwrench-util-css.umd.js": "sha384-4njrao8h2lxvSNG1rwCnRjQnaN23FbqvNQuEe82H6Xao0L2KVI2AfLW5UJndlic6",
45
+ "bitwrench-util-css.umd.min.js": "sha384-V+0Jsx5PDdCkoay8w8durao03+LOtFfrR7tJvhX95h2YprM3Sh/yMmdouSymc2/N",
46
+ "bitwrench.cjs.js": "sha384-223vCHCMFpVn3ebcLzmDhmnjIqpaMe3AcISs02i4qGYbHmnMrnkQmfg95i+l1YSC",
47
+ "bitwrench.cjs.min.js": "sha384-PxbnuQGZgfdu9dtaP6BE1CVRMG8sfMm7rO5tZgFqhVBUDIfHAChGHcXkgB4U3w/N",
48
+ "bitwrench.css": "sha384-nVkVjZaSm8VMx6f0M+cVwaGdjADq/GCwvpO8i6459LBSzKVDb1ezutgwx29kGqd5",
49
+ "bitwrench.es5.js": "sha384-O/K7lCnuhPN4t2Eg2bK/1QRm6Yy3hV9MyaCmPullUzZCXs5LrYTIoLwJyxTUN86R",
50
+ "bitwrench.es5.min.js": "sha384-+nprbfrs5bAbX0e1wX0UhQTIV8c1uEUjN4GeW9aGknKOpSEjP7t+H8ATChzbJeBr",
51
+ "bitwrench.esm.js": "sha384-kESLl4JnEZ6sbx5cX1KkAvDZ4kZ7COx/qMT5RJ5MNc4Udq0zXhtRGigQEzi2fJmX",
52
+ "bitwrench.esm.min.js": "sha384-onhcbWZ1mZlwZHJhSAkU7sEiTvyA4bLFxK1zH7WJ7nquBZflmux1LBxTbZclE0XA",
53
+ "bitwrench.min.css": "sha384-V5byv/NexwbnyMfiTCjVcPPRQpGLP9Ui5DZDl7CnsMgjEpsWY1hG/5j0RpcyXtxS",
54
+ "bitwrench.umd.js": "sha384-d43Dw8mMBWUe3qKHTuIT8mE9Gch/LtTM+W7JtOT66+rx7MNfuwN/Bw1nWx1TDU7P",
55
+ "bitwrench.umd.min.js": "sha384-u/z67Z5XNXTdYWkiEdFZkzZ3MP2Y/irNuZiNDVCr64T1dw8htMANy9BibXaeZ3lR",
56
+ "bwserve.cjs.js": "sha384-0HhE53O4G/J631OQb+bpHNYKc4Th3tldIiXl/04IJhvzbX+ykaQMmujz+JpDrLjZ",
57
+ "bwserve.esm.js": "sha384-W7uLFtAgyaLhIpmC9mjWXQMQijvjoEhlKadxO6AxRwx7M16YKoVRH6f37kC8fxr3"
50
58
  }
51
59
  }
package/docs/README.md CHANGED
@@ -10,6 +10,7 @@ These guides cover how to build UIs with bitwrench.
10
10
  | How do I build a page? | [Building a Website tutorial](tutorial-website.md) |
11
11
  | How does TACO work? | [TACO Format](taco-format.md) or [Thinking in Bitwrench](thinking-in-bitwrench.md) |
12
12
  | How do I add interactivity? | [State Management](state-management.md) |
13
+ | How does a component actually work? | [Component Lifecycle Walkthrough](component-lifecycle.md) |
13
14
  | How do I theme my app? | [Theming](theming.md) |
14
15
  | I'm an LLM generating bitwrench code | [LLM Guide](llm-bitwrench-guide.md) |
15
16
  | How do I use bwmcp with an AI agent? | [bwmcp MCP Server](bitwrench-mcp.md) |
@@ -18,7 +19,7 @@ These guides cover how to build UIs with bitwrench.
18
19
 
19
20
  ## Start Here
20
21
 
21
- - **[Thinking in Bitwrench](thinking-in-bitwrench.md)** -- The complete guide to building with bitwrench. Covers TACO basics, styling (`bw.css`, `bw.s`, `bw.responsive`), composition, the three-level component model, events (and why `onclick` goes in `a:`, not `o.mounted`), bwserve, and common patterns. **Read this first.**
22
+ - **[Thinking in Bitwrench](thinking-in-bitwrench.md)** -- The complete guide to building with bitwrench. Covers TACO basics, styling (`bw.css`, `bw.s`, `bw.responsive`), composition, the component model, events (and why `onclick` goes in `a:`, not `o.mounted`), bwserve, and common patterns. **Read this first.**
22
23
  - **[LLM Guide](llm-bitwrench-guide.md)** -- Compact single-file reference for AI-assisted development. All APIs, patterns, and rules in one document. Also useful as a quick-reference cheat sheet for humans.
23
24
 
24
25
  ## Guides
@@ -27,7 +28,7 @@ These guides cover how to build UIs with bitwrench.
27
28
  |-------|-------------|
28
29
  | [Thinking in Bitwrench](thinking-in-bitwrench.md) | Design philosophy: why TACO exists, component model vs. DOM templates |
29
30
  | [TACO Format](taco-format.md) | The `{t, a, c, o}` object format that bitwrench uses for everything |
30
- | [State Management](state-management.md) | Three-level component model, reactive state, cross-component communication |
31
+ | [State Management](state-management.md) | Component model, explicit stateful components, cross-component communication |
31
32
  | [Component Cheat Sheet](component-cheatsheet.md) | Scannable table of all components with capabilities and handles |
32
33
  | [Component Library](component-library.md) | All `make*()` functions with full signatures and examples |
33
34
  | [Routing](routing.md) | Client-side router: hash/history mode, route params, guards, pub/sub |
@@ -39,6 +40,7 @@ These guides cover how to build UIs with bitwrench.
39
40
  | [LLM Guide](llm-bitwrench-guide.md) | Compact single-file reference for AI-assisted development |
40
41
  | [TypeScript Usage Guide](bitwrench_typescript_usage.md) | Import patterns, typed configs, TACO types, tree-shaking |
41
42
  | [bwmcp MCP Server](bitwrench-mcp.md) | MCP server for AI agents: tool catalog, live rendering, screenshots |
43
+ | [drift-lint](drift-lint.md) | Maintainer tool: keeps docs/examples consistent with the shipped API |
42
44
 
43
45
  ## Tutorials
44
46
 
@@ -47,6 +49,7 @@ These guides cover how to build UIs with bitwrench.
47
49
  | [Building a Website](tutorial-website.md) | Build a complete landing page from scratch |
48
50
  | [Server App with bwserve](tutorial-bwserve.md) | Build a Streamlit-style server-driven dashboard |
49
51
  | [ESP32 Embedded](tutorial-embedded.md) | ESP32 IoT dashboard with C/C++ macros |
52
+ | [Component Lifecycle Walkthrough](component-lifecycle.md) | Stats card: define, create, mount, update, unmount — every phase of a v2.1 component |
50
53
 
51
54
  ## Interactive Docs
52
55
 
@@ -72,7 +75,7 @@ The library provides four things:
72
75
 
73
76
  1. **A rendering engine** that turns objects into HTML or DOM
74
77
  2. **A component library** of ready-made UI elements
75
- 3. **A reactivity system** that updates the DOM when state changes
78
+ 3. **An explicit update model** components live on the DOM element itself (`el.bw` methods, slots, `el._bw_state`), and updates happen when you call them (`el.bw.method()`, `bw.update()`, `bw.refresh()`)
76
79
  4. **A client-side router** that maps URLs to views with guards and pub/sub
77
80
 
78
81
  Everything else -- styling, theming, event handling, server communication -- builds on these pieces.
@@ -139,24 +139,24 @@ var app = bwserve.create({ port: 7902 });
139
139
  var count = 0;
140
140
 
141
141
  app.page('/', function(client) {
142
- client.render('#app', {
142
+ client.mount('#app', {
143
143
  t: 'div', c: [
144
144
  { t: 'h1', c: 'Server Counter' },
145
145
  { t: 'span', a: { id: 'val' }, c: '0' },
146
- { t: 'button', a: { 'data-bw-action': 'inc' }, c: '+1' }
146
+ { t: 'button', a: { class: 'bw_act_inc' }, c: '+1' }
147
147
  ]
148
148
  });
149
149
 
150
150
  client.on('inc', function() {
151
151
  count++;
152
- client.patch('val', String(count));
152
+ client.patch('val', { text: String(count) });
153
153
  });
154
154
  });
155
155
 
156
156
  app.listen();
157
157
  ```
158
158
 
159
- **State flow:** Browser requests `/` => server returns HTML shell. Shell opens SSE => server sends TACO via `client.render()`. User clicks `data-bw-action` => browser POSTs to server. Server calls `client.patch()` => browser updates. All state stays on the server. See [bwserve.md](bwserve.md).
159
+ **State flow:** Browser requests `/` => server returns HTML shell. Shell opens SSE => server sends TACO via `client.mount()`. User clicks a `bw_act_*` classed element => browser POSTs to server. Server calls `client.patch()` => browser updates. All state stays on the server. See [bwserve.md](bwserve.md).
160
160
 
161
161
  ---
162
162
 
@@ -189,7 +189,8 @@ bw.DOM('#app', { t: 'div', c: [
189
189
  }})
190
190
  ]});
191
191
 
192
- // Poll the device -- re-render readings section each cycle
192
+ // Quick prototype: poll + full re-render. For production, use SSE
193
+ // with bw.patch() instead -- see tutorial-embedded.md for the SSE version.
193
194
  setInterval(function() {
194
195
  fetch('/api/sensors').then(function(r) { return r.json(); })
195
196
  .then(function(data) {
@@ -244,7 +245,7 @@ Each output is self-contained with bitwrench embedded inline. No CDN, no toolcha
244
245
  |----------|---------|---------|
245
246
  | Monitoring dashboard, admin panel | Single-Page Dashboard | `bw.pub/sub`, `bw.DOM()`, `makeStatCard` |
246
247
  | Multi-view app with URL navigation | Multi-Page SPA | `bw.router()`, `bw.navigate()` |
247
- | Server owns all logic (internal tool, LLM UI) | bwserve Server-Driven | `client.render()`, `client.patch()` |
248
+ | Server owns all logic (internal tool, LLM UI) | bwserve Server-Driven | `client.mount()`, `client.patch()` |
248
249
  | Microcontroller or constrained device | Embedded / IoT | `bw.DOM()`, `fetch()` polling or SSE |
249
250
  | Documentation, blog, project pages | Static Site (bwcli) | `bwcli`, `--theme`, `--standalone` |
250
251
  | Prototype or quick one-off | Single-Page Dashboard | One HTML file, no build step |
@@ -52,7 +52,7 @@ Each boundary crossing has overhead: type marshaling, memory copying, function d
52
52
 
53
53
  ### An alternative: batch the boundary
54
54
 
55
- A different approach is to cross the boundary **once per render, not once per DOM operation.** The WASM module builds a TACO object (a JSON-serializable data structure) and sends it across the boundary as a single message. The JS-side library materializes the entire tree in one shot using `bw.createDOM()` or `bw.DOM()`.
55
+ A different approach is to cross the boundary **once per render, not once per DOM operation.** The WASM module builds a TACO object (a JSON-serializable data structure) and sends it across the boundary as a single message. The JS-side library materializes the entire tree in one shot using `bw.create()` or `bw.DOM()`.
56
56
 
57
57
  ```
58
58
  WASM side JS side (bitwrench)
@@ -72,7 +72,7 @@ Serialize to JSON string |
72
72
 
73
73
  100 elements = 1 crossing, not 300+. The DOM operations happen inside JS where they're native function calls with zero marshaling overhead.
74
74
 
75
- For incremental updates, the same principle applies. Instead of diffing an entire virtual tree across the boundary, the WASM module sends a targeted patch message: `{type: 'patch', target: '#counter', content: '42'}`. One crossing, one DOM mutation.
75
+ For incremental updates, the same principle applies. Instead of diffing an entire virtual tree across the boundary, the WASM module sends a targeted patch message: `{v: 1, type: 'patch', ref: '#counter', text: '42'}`. One crossing, one DOM mutation.
76
76
 
77
77
  ---
78
78
 
@@ -117,7 +117,7 @@ The fourth key, `o:`, contains JavaScript-specific concerns: lifecycle hooks (`m
117
117
 
118
118
  For WASM, this split is a natural fit: the **specification** (what to render) crosses the boundary as data, while the **behavior** (DOM event handling, lifecycle management) stays in JS where DOM access is native.
119
119
 
120
- For cases where the WASM module needs to define behavior, bwserve provides `register` and `call` -- send a function string once, invoke it by name later. This keeps the boundary thin while allowing the WASM side to install client-side logic when needed.
120
+ For cases where the WASM module needs to invoke client-side behavior, bwserve provides `call` -- invoke a named built-in function (e.g., `scrollTo`, `focus`, `download`). Code-bearing verbs (`register`, `exec`) were removed in v2.1; client-side logic should be pre-installed via the JS glue or BCCL component handles.
121
121
 
122
122
  ---
123
123
 
@@ -127,19 +127,18 @@ bwserve is bitwrench's server-driven UI protocol. It was originally designed for
127
127
 
128
128
  ### The protocol
129
129
 
130
- Nine message types. Five for DOM operations, three for code execution, one for component dispatch:
130
+ All messages are stamped with `v: 1`. The v2.1 protocol has the following verb set (code-bearing verbs `exec`, `register`, and `query` were removed):
131
131
 
132
132
  | Type | What it does | Example |
133
133
  |------|-------------|---------|
134
- | `replace` | Replace element subtree | `{type:'replace', target:'#app', node:{t:'div', c:'Hello'}}` |
135
- | `patch` | Update text or attributes | `{type:'patch', target:'counter', content:'42'}` |
136
- | `append` | Add child element | `{type:'append', target:'#list', node:{t:'li', c:'New'}}` |
137
- | `remove` | Delete element | `{type:'remove', target:'#old'}` |
138
- | `batch` | Multiple operations | `{type:'batch', ops:[...]}` |
139
- | `register` | Send named function | `{type:'register', name:'scroll', body:'function(s){...}'}` |
140
- | `call` | Invoke function by name | `{type:'call', name:'scroll', args:['#chat']}` |
141
- | `exec` | Run arbitrary JS | `{type:'exec', code:'document.title="Hi"'}` |
142
- | `message` | Component dispatch | `{type:'message', target:'#card', action:'setTitle', data:'New'}` |
134
+ | `mount` | Mount TACO at selector | `{v:1, type:'mount', ref:'#app', taco:{t:'div', c:'Hello'}}` |
135
+ | `patch` | Update text or attributes (discriminated fields) | `{v:1, type:'patch', ref:'counter', text:'42'}` |
136
+ | `append` | Add child element | `{v:1, type:'append', ref:'#list', taco:{t:'li', c:'New'}}` |
137
+ | `remove` | Delete element | `{v:1, type:'remove', ref:'#old'}` |
138
+ | `batch` | Multiple operations | `{v:1, type:'batch', ops:[...]}` |
139
+ | `call` | Invoke a named built-in function | `{v:1, type:'call', name:'scrollTo', args:['#chat']}` |
140
+ | `message` | Component dispatch | `{v:1, type:'message', ref:'#card', action:'setTitle', data:'New'}` |
141
+ | `listen` | Subscribe to a pub/sub topic | `{v:1, type:'listen', topic:'bw:lifecycle'}` |
143
142
 
144
143
  ### The full loop
145
144
 
@@ -148,12 +147,12 @@ WASM Module (application) Browser (display server)
148
147
  ------------------------- -----------------------
149
148
  State + logic bitwrench + bwserve client
150
149
  | |
151
- |-- replace: full render --------> bw.apply() -> bw.DOM()
150
+ |-- mount: full render ----------> bw.apply() -> bw.mount()
152
151
  |-- patch: targeted update ------> bw.apply() -> bw.patch()
153
152
  |-- call: scroll, focus, etc. ---> bw.apply() -> invoke function
154
153
  |-- batch: multiple ops ---------> bw.apply() -> sequential
155
154
  | |
156
- <-- event: {target, type, data} -- subscribed listener fires
155
+ <-- event: {ref, type, data} ---- subscribed listener fires
157
156
  <-- screenshot: PNG buffer ------- html2canvas -> POST-back
158
157
  ```
159
158
 
@@ -292,7 +291,7 @@ WASM server binary Browser
292
291
  | |
293
292
  |-- GET / -> HTML shell ---------->|
294
293
  |-- GET /bw/events -> SSE -------->|
295
- |-- SSE: replace/patch/etc ------->| bw.apply() -> DOM
294
+ |-- SSE: mount/patch/etc -------->| bw.apply() -> DOM
296
295
  |<-- POST /bw/return/action -------|
297
296
  |<-- POST /bw/return/screenshot ---|
298
297
  ```
@@ -319,16 +318,16 @@ use serde_json::json;
319
318
 
320
319
  fn render_dashboard(state: &AppState) -> String {
321
320
  json!({
322
- "t": "div", "a": {"class": "bw-container"}, "c": [
321
+ "t": "div", "a": {"class": "bw_container"}, "c": [
323
322
  {"t": "h1", "c": &state.title},
324
- {"t": "div", "a": {"class": "bw-row"}, "c": [
323
+ {"t": "div", "a": {"class": "bw_row"}, "c": [
325
324
  stat_card("Users", &state.users.to_string(), "primary"),
326
325
  stat_card("Revenue", &format!("${}", state.revenue), "success"),
327
326
  stat_card("Orders", &state.orders.to_string(), "info")
328
327
  ]},
329
328
  {"t": "button", "a": {
330
329
  "id": "refresh-btn",
331
- "class": "bw-btn bw-btn-primary"
330
+ "class": "bw_bccl_btn bw_primary"
332
331
  }, "c": "Refresh"}
333
332
  ]
334
333
  }).to_string()
@@ -336,9 +335,9 @@ fn render_dashboard(state: &AppState) -> String {
336
335
 
337
336
  fn stat_card(label: &str, value: &str, variant: &str) -> serde_json::Value {
338
337
  json!({
339
- "t": "div", "a": {"class": format!("bw-stat-card bw-stat-card-{}", variant)}, "c": [
340
- {"t": "div", "a": {"class": "bw-stat-card-value"}, "c": value},
341
- {"t": "div", "a": {"class": "bw-stat-card-label"}, "c": label}
338
+ "t": "div", "a": {"class": format!("bw_bccl_stat_card bw_{}", variant)}, "c": [
339
+ {"t": "div", "a": {"class": "bw_bccl_stat_card_value"}, "c": value},
340
+ {"t": "div", "a": {"class": "bw_bccl_stat_card_label"}, "c": label}
342
341
  ]
343
342
  })
344
343
  }
@@ -372,22 +371,22 @@ pub fn div(attrs: Value, children: Vec<Value>) -> Value {
372
371
  pub fn button(label: &str, id: &str) -> Value {
373
372
  json!({
374
373
  "t": "button",
375
- "a": {"id": id, "class": "bw-btn bw-btn-primary"},
374
+ "a": {"id": id, "class": "bw_bccl_btn bw_primary"},
376
375
  "c": label
377
376
  })
378
377
  }
379
378
 
380
- // bwserve protocol messages
381
- pub fn msg_replace(target: &str, node: Value) -> Value {
382
- json!({"type": "replace", "target": target, "node": node})
379
+ // bwserve v2.1 protocol messages (all stamped v:1)
380
+ pub fn msg_mount(r: &str, taco: Value) -> Value {
381
+ json!({"v": 1, "type": "mount", "ref": r, "taco": taco})
383
382
  }
384
383
 
385
- pub fn msg_patch(target: &str, content: &str) -> Value {
386
- json!({"type": "patch", "target": target, "content": content})
384
+ pub fn msg_patch(r: &str, text: &str) -> Value {
385
+ json!({"v": 1, "type": "patch", "ref": r, "text": text})
387
386
  }
388
387
 
389
388
  pub fn msg_batch(ops: Vec<Value>) -> Value {
390
- json!({"type": "batch", "ops": ops})
389
+ json!({"v": 1, "type": "batch", "ops": ops})
391
390
  }
392
391
  ```
393
392
 
@@ -397,7 +396,7 @@ With this helper:
397
396
  use taco::*;
398
397
 
399
398
  fn render(state: &AppState) -> String {
400
- msg_replace("#app", div(
399
+ msg_mount("#app", div(
401
400
  json!({"class": "container"}),
402
401
  vec![
403
402
  text("h1", &state.title),
@@ -487,14 +486,14 @@ Standard JSON in C requires escaping every double quote:
487
486
 
488
487
  ```c
489
488
  // Standard JSON -- escape nightmare
490
- char msg[] = "{\"type\":\"patch\",\"target\":\"temp\",\"content\":\"23.5 C\"}";
489
+ char msg[] = "{\"v\":1,\"type\":\"patch\",\"ref\":\"temp\",\"text\":\"23.5 C\"}";
491
490
  ```
492
491
 
493
492
  Bitwrench's r-prefix format uses single quotes:
494
493
 
495
494
  ```c
496
495
  // r-prefix relaxed JSON -- natural C strings
497
- char msg[] = "r{'type':'patch','target':'temp','content':'23.5 C'}";
496
+ char msg[] = "r{'v':1,'type':'patch','ref':'temp','text':'23.5 C'}";
498
497
  ```
499
498
 
500
499
  `bw.parseJSONFlex()` on the browser side converts single quotes to double quotes before parsing. The `r` prefix signals the format.
@@ -505,16 +504,16 @@ char msg[] = "r{'type':'patch','target':'temp','content':'23.5 C'}";
505
504
  #include <stdio.h>
506
505
  #include <string.h>
507
506
 
508
- // Simple TACO builder macros for fixed-size buffers
509
- #define BW_PATCH(buf, target, content) \
507
+ // Simple TACO builder macros for fixed-size buffers (v2.1 wire protocol)
508
+ #define BW_PATCH(buf, ref, text) \
510
509
  snprintf(buf, sizeof(buf), \
511
- "r{'type':'patch','target':'%s','content':'%s'}", \
512
- target, content)
510
+ "r{'v':1,'type':'patch','ref':'%s','text':'%s'}", \
511
+ ref, text)
513
512
 
514
- #define BW_REPLACE(buf, target, taco) \
513
+ #define BW_MOUNT(buf, ref, taco) \
515
514
  snprintf(buf, sizeof(buf), \
516
- "r{'type':'replace','target':'%s','node':%s}", \
517
- target, taco)
515
+ "r{'v':1,'type':'mount','ref':'%s','taco':%s}", \
516
+ ref, taco)
518
517
 
519
518
  // TACO builders
520
519
  #define TACO_TEXT(buf, tag, text) \
@@ -557,11 +556,11 @@ const char* render() {
557
556
  float temp = read_sensor();
558
557
 
559
558
  snprintf(buf, sizeof(buf),
560
- "r{'type':'replace','target':'#app','node':"
559
+ "r{'v':1,'type':'mount','ref':'#app','taco':"
561
560
  "{'t':'div','c':["
562
561
  "{'t':'h1','c':'Sensor Dashboard'},"
563
562
  "{'t':'p','a':{'id':'temp'},'c':'%.1f C'},"
564
- "{'t':'button','a':{'id':'toggle-btn','class':'bw-btn'},"
563
+ "{'t':'button','a':{'id':'toggle-btn','class':'bw_bccl_btn'},"
565
564
  "'c':'Toggle LED'}"
566
565
  "]}}", temp);
567
566
 
@@ -601,7 +600,7 @@ AI models typically output structured data -- JSON, function calls, tool use. TA
601
600
  {"t": "div", "c": [
602
601
  {"t": "h2", "c": "Analysis Results"},
603
602
  {"t": "p", "c": "Found 3 anomalies in the dataset."},
604
- {"t": "div", "a": {"class": "bw-card"}, "c": [
603
+ {"t": "div", "a": {"class": "bw_bccl_card"}, "c": [
605
604
  {"t": "h3", "c": "Anomaly #1"},
606
605
  {"t": "p", "c": "Temperature spike at 14:32 UTC"}
607
606
  ]},
@@ -619,7 +618,7 @@ bwserve's screenshot capability closes the loop. The AI generates UI, the browse
619
618
  AI Model (WASM) Browser
620
619
  ----------- -------
621
620
  Generate TACO spec |
622
- |-- replace: render UI --------> bw.DOM() -> visible page
621
+ |-- mount: render UI ----------> bw.apply() -> visible page
623
622
  | |
624
623
  |-- screenshot request --------> html2canvas -> capture
625
624
  <-- PNG image data -------------|
@@ -629,7 +628,7 @@ Evaluate screenshot |
629
628
  text overflow? wrong layout?) |
630
629
  | |
631
630
  Generate refined TACO spec |
632
- |-- replace: updated UI -------> bw.DOM() -> improved page
631
+ |-- mount: updated UI ---------> bw.apply() -> improved page
633
632
  ```
634
633
 
635
634
  bwserve implements `client.screenshot()` for this purpose -- it sends a `call` message that triggers `html2canvas` on the client, which captures the DOM to a canvas, converts to PNG, and POSTs the image data back to the server. The server resolves a Promise with the image buffer.
@@ -673,10 +672,10 @@ fn agent_step(state: &AgentState) -> Vec<Value> {
673
672
  let mut messages = vec![];
674
673
 
675
674
  // Main content area -- task-specific UI
676
- messages.push(msg_replace("#main", render_task_ui(&state.current_task)));
675
+ messages.push(msg_mount("#main", render_task_ui(&state.current_task)));
677
676
 
678
677
  // Sidebar -- agent's reasoning visible to user
679
- messages.push(msg_replace("#sidebar", render_reasoning_log(&state.log)));
678
+ messages.push(msg_mount("#sidebar", render_reasoning_log(&state.log)));
680
679
 
681
680
  // Status bar -- progress and controls
682
681
  messages.push(msg_patch("status", &format!(
@@ -730,7 +729,7 @@ One patch message, one DOM mutation. The WASM module communicates what it alread
730
729
 
731
730
  Desktop UI toolkits (MFC, Swing, Qt, Cocoa) used targeted updates rather than tree diffing. In MFC, `SetWindowText("New Title")` repainted the control's title. In Swing, `label.setText("43")` updated one label. In Qt, signal-slot connections trigger specific updates. The application tracked what changed and told the framework directly.
732
731
 
733
- bitwrench follows the same pattern: `el.bw.setTitle('New')` updates one component, `bw.patch('#counter', '43')` updates one element, `client.patch('counter', '43')` sends one message. The application (or the WASM module) is the source of truth about what changed.
732
+ bitwrench follows the same pattern: `el.bw.setTitle('New')` updates one component, `bw.patch('#counter', '43')` updates one element, `client.patch('counter', {text: '43'})` sends one message. The application (or the WASM module) is the source of truth about what changed.
734
733
 
735
734
  React's diffing approach solved a real problem -- in large JS applications with shared mutable state, manually tracking dependencies is error-prone. Whether that tradeoff applies to a given WASM application depends on the application's complexity and state management approach.
736
735
 
@@ -740,7 +739,7 @@ If your WASM module genuinely doesn't know what changed -- for example, if it re
740
739
 
741
740
  1. Diff the **data** in WASM (compare old state to new state)
742
741
  2. Emit targeted patches for what changed
743
- 3. Or, for small enough UIs, just re-render with `replace` -- `bw.DOM()` is fast enough for most subtrees
742
+ 3. Or, for small enough UIs, just re-render with `mount` -- `bw.DOM()` is fast enough for most subtrees
744
743
 
745
744
  Diffing data in WASM (where you have typed structs and linear memory) is cheaper than diffing virtual DOM trees in JS (where everything is heap-allocated objects with GC pressure).
746
745
 
@@ -762,7 +761,7 @@ These are the most direct alternatives. They run a component framework inside WA
762
761
  | Accessibility | Manual | Browser-native (real HTML) |
763
762
  | Server rendering | Framework-specific SSR | bw.html() or bwserve |
764
763
  | Learning curve | Rust + framework | Rust + TACO (4 keys) |
765
- | Bundle size | ~200KB+ (framework + app) | ~40KB (bitwrench) + app WASM |
764
+ | Bundle size | ~200KB+ (framework + app) | ~45KB (bitwrench) + app WASM |
766
765
 
767
766
  The fundamental difference is where the component model lives. Yew/Leptos/Dioxus place it in WASM (Rust macros, reactive primitives, virtual DOM). The bitwrench approach places it in JS (TACO rendering, CSS generation, component handles) and uses JSON as the interface between the application language and the renderer.
768
767
 
@@ -770,7 +769,7 @@ The fundamental difference is where the component model lives. Yew/Leptos/Dioxus
770
769
 
771
770
  | Concern | Blazor | bitwrench + WASM |
772
771
  |---------|--------|------------------|
773
- | Runtime payload | 2-5MB (.NET in WASM) | ~40KB (bitwrench) |
772
+ | Runtime payload | 2-5MB (.NET in WASM) | ~45KB (bitwrench) |
774
773
  | Component model | Razor templates (.NET) | TACO JSON |
775
774
  | DOM access | JS interop bridge | Batched via bw.apply() |
776
775
  | Language | C# only | Any (Rust, C, C++, Go, ...) |
@@ -786,7 +785,7 @@ Blazor bundles a language runtime in WASM. The bitwrench approach does not requi
786
785
  | Backend | Native process (Rust/Node) | WASM (in-browser or server) |
787
786
  | Frontend | You write JS/React/Vue | TACO from any language |
788
787
  | Distribution | App store / download | Link sharing |
789
- | Bundle size | 10-100MB+ | Page weight (~40KB + WASM) |
788
+ | Bundle size | 10-100MB+ | Page weight (~45KB + WASM) |
790
789
 
791
790
  Tauri and Electron are designed for desktop application distribution. If the UI can be served as a web page, the packaging and distribution step is not needed -- the tradeoff is losing native OS integration (system tray, menus, file system access without permissions).
792
791
 
@@ -811,8 +810,8 @@ Canvas-based approaches bypass the browser's built-in UI capabilities. Generatin
811
810
 
812
811
  - Browser-native UI (real HTML/CSS) from any language that produces JSON
813
812
  - Batched boundary crossing -- one message per render, not one per DOM op
814
- - 9-verb protocol (bwserve) for remote UI control including screenshots
815
- - ~40KB client library with 30+ components, CSS generation, theming
813
+ - Structured protocol (bwserve, v:1 stamped) for remote UI control including screenshots
814
+ - ~45KB client library with 30+ components, CSS generation, theming
816
815
  - No build step on the JS side
817
816
  - Same application code can target in-page WASM, Worker, or native server
818
817
  - Browser capabilities preserved: accessibility, text selection, CSS layout, forms
@@ -823,7 +822,7 @@ Canvas-based approaches bypass the browser's built-in UI capabilities. Generatin
823
822
 
824
823
  - **No automatic change detection.** You must know what changed and say so. (This is usually trivial in WASM where you just ran the mutation.)
825
824
  - **No type-safe TACO builder in Rust/C** -- you're building JSON. A helper crate/header can add convenience, but there's no compile-time guarantee that your TACO is valid. (bitwrench is lenient -- invalid fields are silently ignored.)
826
- - **No client-side routing from WASM.** The browser-side `bw.router()` exists for JS, but a WASM server would manage navigation via bwserve's `replace` messages.
825
+ - **No client-side routing from WASM.** The browser-side `bw.router()` exists for JS, but a WASM server would manage navigation via bwserve's `mount` messages.
827
826
  - **No two-way data binding.** User events come back as structured messages (element ID, event type, value). You update your state and send a patch. This is the expected pattern for a boundary architecture.
828
827
  - **No animation primitives from WASM.** CSS animations and transitions work (they're in the browser), but you'd define them via `bw.css()` on the JS side or in a stylesheet, not from WASM.
829
828
 
@@ -222,7 +222,7 @@ This costs about 200 tokens. Always call it first.
222
222
  ### Step 2: Learn (Optional but Recommended)
223
223
 
224
224
  If you have not used bitwrench before, call `bitwrench_guide`. This is the
225
- full tutorial (about 4000 tokens). It covers TACO nesting, the three-level
225
+ full tutorial (about 4000 tokens). It covers TACO nesting, the
226
226
  component model, events, CSS/theming, all component categories, debugging,
227
227
  bwserve, routing, and API reference tables.
228
228
 
@@ -299,7 +299,7 @@ If using live rendering:
299
299
  ```
300
300
  screenshot({}) // see what the browser shows
301
301
  screenshot({selector: '.bw_stat_card:first-child'}) // zoom in on one element
302
- query_dom({code: 'document.querySelectorAll(".bw_card").length'}) // count cards
302
+ query_dom({code: 'bw.$(\'.bw_bccl_card\').length'}) // count cards
303
303
  ```
304
304
 
305
305
  Evaluate the screenshot, decide what to change, and call `render_live` again.