bitwrench 2.0.22 → 2.0.23

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 (88) hide show
  1. package/LICENSE.txt +1 -1
  2. package/README.md +4 -3
  3. package/bin/bwmcp.js +3 -0
  4. package/dist/bitwrench-bccl.cjs.js +1 -1
  5. package/dist/bitwrench-bccl.cjs.min.js +1 -1
  6. package/dist/bitwrench-bccl.cjs.min.js.gz +0 -0
  7. package/dist/bitwrench-bccl.esm.js +1 -1
  8. package/dist/bitwrench-bccl.esm.min.js +1 -1
  9. package/dist/bitwrench-bccl.esm.min.js.gz +0 -0
  10. package/dist/bitwrench-bccl.umd.js +1 -1
  11. package/dist/bitwrench-bccl.umd.min.js +1 -1
  12. package/dist/bitwrench-bccl.umd.min.js.gz +0 -0
  13. package/dist/bitwrench-code-edit.cjs.js +1 -1
  14. package/dist/bitwrench-code-edit.cjs.min.js +1 -1
  15. package/dist/bitwrench-code-edit.es5.js +1 -1
  16. package/dist/bitwrench-code-edit.es5.min.js +1 -1
  17. package/dist/bitwrench-code-edit.esm.js +1 -1
  18. package/dist/bitwrench-code-edit.esm.min.js +1 -1
  19. package/dist/bitwrench-code-edit.umd.js +1 -1
  20. package/dist/bitwrench-code-edit.umd.min.js +1 -1
  21. package/dist/bitwrench-code-edit.umd.min.js.gz +0 -0
  22. package/dist/bitwrench-debug.js +1 -1
  23. package/dist/bitwrench-debug.min.js +1 -1
  24. package/dist/bitwrench-lean.cjs.js +3 -3
  25. package/dist/bitwrench-lean.cjs.min.js +2 -2
  26. package/dist/bitwrench-lean.cjs.min.js.gz +0 -0
  27. package/dist/bitwrench-lean.es5.js +3 -3
  28. package/dist/bitwrench-lean.es5.min.js +2 -2
  29. package/dist/bitwrench-lean.es5.min.js.gz +0 -0
  30. package/dist/bitwrench-lean.esm.js +3 -3
  31. package/dist/bitwrench-lean.esm.min.js +2 -2
  32. package/dist/bitwrench-lean.esm.min.js.gz +0 -0
  33. package/dist/bitwrench-lean.umd.js +3 -3
  34. package/dist/bitwrench-lean.umd.min.js +2 -2
  35. package/dist/bitwrench-lean.umd.min.js.gz +0 -0
  36. package/dist/bitwrench-util-css.cjs.js +1 -1
  37. package/dist/bitwrench-util-css.cjs.min.js +1 -1
  38. package/dist/bitwrench-util-css.es5.js +1 -1
  39. package/dist/bitwrench-util-css.es5.min.js +1 -1
  40. package/dist/bitwrench-util-css.esm.js +1 -1
  41. package/dist/bitwrench-util-css.esm.min.js +1 -1
  42. package/dist/bitwrench-util-css.umd.js +1 -1
  43. package/dist/bitwrench-util-css.umd.min.js +1 -1
  44. package/dist/bitwrench-util-css.umd.min.js.gz +0 -0
  45. package/dist/bitwrench.cjs.js +3 -3
  46. package/dist/bitwrench.cjs.min.js +2 -2
  47. package/dist/bitwrench.cjs.min.js.gz +0 -0
  48. package/dist/bitwrench.css +1 -1
  49. package/dist/bitwrench.es5.js +3 -3
  50. package/dist/bitwrench.es5.min.js +2 -2
  51. package/dist/bitwrench.es5.min.js.gz +0 -0
  52. package/dist/bitwrench.esm.js +3 -3
  53. package/dist/bitwrench.esm.min.js +2 -2
  54. package/dist/bitwrench.esm.min.js.gz +0 -0
  55. package/dist/bitwrench.umd.js +3 -3
  56. package/dist/bitwrench.umd.min.js +2 -2
  57. package/dist/bitwrench.umd.min.js.gz +0 -0
  58. package/dist/builds.json +57 -57
  59. package/dist/bwserve.cjs.js +2 -2
  60. package/dist/bwserve.esm.js +2 -2
  61. package/dist/sri.json +45 -45
  62. package/docs/README.md +76 -0
  63. package/docs/app-patterns.md +264 -0
  64. package/docs/bitwrench-mcp.md +426 -0
  65. package/docs/bitwrench_api.md +2232 -0
  66. package/docs/bw-attach.md +399 -0
  67. package/docs/bwserve.md +841 -0
  68. package/docs/cli.md +307 -0
  69. package/docs/component-cheatsheet.md +144 -0
  70. package/docs/component-library.md +1099 -0
  71. package/docs/framework-translation-table.md +33 -0
  72. package/docs/llm-bitwrench-guide.md +672 -0
  73. package/docs/routing.md +562 -0
  74. package/docs/state-management.md +767 -0
  75. package/docs/taco-format.md +373 -0
  76. package/docs/theming.md +309 -0
  77. package/docs/thinking-in-bitwrench.md +1457 -0
  78. package/docs/tutorial-bwserve.md +297 -0
  79. package/docs/tutorial-embedded.md +314 -0
  80. package/docs/tutorial-website.md +255 -0
  81. package/package.json +11 -3
  82. package/readme.html +5 -4
  83. package/src/mcp/knowledge.js +231 -0
  84. package/src/mcp/live.js +226 -0
  85. package/src/mcp/server.js +216 -0
  86. package/src/mcp/tools.js +369 -0
  87. package/src/mcp/transport.js +55 -0
  88. package/src/version.js +3 -3
@@ -0,0 +1,255 @@
1
+ # Tutorial: Building a Website with Bitwrench
2
+
3
+ This tutorial walks through building a complete, styled website using bitwrench — from a blank HTML file to a multi-section landing page with theme, navigation, and responsive layout.
4
+
5
+ ## What you'll build
6
+
7
+ A product landing page with:
8
+ - Navigation bar
9
+ - Hero section with call-to-action
10
+ - Feature grid
11
+ - Pricing cards
12
+ - Contact form with handle-based validation
13
+ - Footer
14
+
15
+ Total code: ~120 lines of JavaScript. No build step.
16
+
17
+ ## Step 1: Start with a blank page
18
+
19
+ Create `index.html`:
20
+
21
+ ```html
22
+ <!DOCTYPE html>
23
+ <html lang="en">
24
+ <head>
25
+ <meta charset="UTF-8">
26
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
27
+ <title>My Product</title>
28
+ <script src="https://cdn.jsdelivr.net/npm/bitwrench/dist/bitwrench.umd.min.js"></script>
29
+ </head>
30
+ <body>
31
+ <div id="app"></div>
32
+ <script>
33
+ // We'll build everything here
34
+ bw.loadStyles();
35
+ bw.DOM('#app', { t: 'h1', c: 'Hello bitwrench!' });
36
+ </script>
37
+ </body>
38
+ </html>
39
+ ```
40
+
41
+ Open it in a browser. You should see styled "Hello bitwrench!" text.
42
+
43
+ ## Step 2: Add a theme
44
+
45
+ Replace the script contents with:
46
+
47
+ ```javascript
48
+ bw.loadStyles();
49
+ bw.loadStyles({
50
+ primary: '#2563eb',
51
+ secondary: '#7c3aed',
52
+ spacing: 'normal',
53
+ radius: 'md'
54
+ });
55
+
56
+ bw.DOM('#app', { t: 'h1', c: 'Themed heading' });
57
+ ```
58
+
59
+ Every bitwrench component now uses your brand colors automatically.
60
+
61
+ ## Step 3: Build the navigation
62
+
63
+ ```javascript
64
+ var nav = bw.makeNavbar({
65
+ brand: 'Acme',
66
+ items: [
67
+ { text: 'Features', href: '#features' },
68
+ { text: 'Pricing', href: '#pricing' },
69
+ { text: 'Contact', href: '#contact' }
70
+ ]
71
+ });
72
+ ```
73
+
74
+ `makeNavbar()` returns a TACO object — plain data, not DOM. Nothing is rendered yet.
75
+
76
+ ## Step 4: Build the hero section
77
+
78
+ ```javascript
79
+ var hero = bw.makeHero({
80
+ title: 'Ship faster with Acme',
81
+ subtitle: 'The developer toolkit that gets out of your way.',
82
+ actions: [
83
+ bw.makeButton({ text: 'Get Started', variant: 'primary', size: 'lg' }),
84
+ bw.makeButton({ text: 'Learn More', variant: 'secondary', size: 'lg' })
85
+ ]
86
+ });
87
+ ```
88
+
89
+ ## Step 5: Build the feature grid
90
+
91
+ ```javascript
92
+ var features = bw.makeFeatureGrid({
93
+ columns: 3,
94
+ features: [
95
+ { icon: 'bolt', title: 'Fast', desc: 'No build step, no virtual DOM. Just objects and functions.' },
96
+ { icon: 'shield', title: 'Reliable', desc: '100% test coverage. Works in IE11 through modern browsers.' },
97
+ { icon: 'code', title: 'Simple', desc: 'One file, ~40KB gzipped. Zero dependencies. Learn in an afternoon.' }
98
+ ]
99
+ });
100
+ ```
101
+
102
+ ## Step 6: Add pricing cards
103
+
104
+ ```javascript
105
+ var pricing = {
106
+ t: 'section', a: { id: 'pricing', style: 'padding: 3rem 1rem; text-align: center' },
107
+ c: [
108
+ { t: 'h2', c: 'Pricing' },
109
+ {
110
+ t: 'div', a: { style: 'display: flex; gap: 1.5rem; justify-content: center; flex-wrap: wrap; margin-top: 2rem' },
111
+ c: [
112
+ bw.makeCard({ title: 'Free', content: '$0/mo -- For personal projects', footer: bw.makeButton({ text: 'Start Free', variant: 'secondary' }) }),
113
+ bw.makeCard({ title: 'Pro', content: '$29/mo -- For teams', footer: bw.makeButton({ text: 'Subscribe', variant: 'primary' }) }),
114
+ bw.makeCard({ title: 'Enterprise', content: 'Custom -- Contact us', footer: bw.makeButton({ text: 'Contact Sales', variant: 'secondary' }) })
115
+ ]
116
+ }
117
+ ]
118
+ };
119
+ ```
120
+
121
+ This mixes `make*()` components with raw TACO for layout. Both work together — TACO objects nest freely.
122
+
123
+ ## Step 7: Add a contact form
124
+
125
+ ```javascript
126
+ var contact = {
127
+ t: 'section', a: { id: 'contact', style: 'padding: 3rem 1rem; max-width: 600px; margin: 0 auto' },
128
+ c: [
129
+ { t: 'h2', c: 'Contact Us' },
130
+ bw.makeForm({
131
+ children: [
132
+ bw.makeFormGroup({ label: 'Name', input: bw.makeInput({ type: 'text', placeholder: 'Jane Smith' }) }),
133
+ bw.makeFormGroup({ label: 'Email', input: bw.makeInput({ type: 'email', placeholder: 'jane@example.com' }) }),
134
+ bw.makeFormGroup({ label: 'Message', input: bw.makeTextarea({ placeholder: 'How can we help?' }) }),
135
+ bw.makeButton({ text: 'Send Message', type: 'submit', variant: 'primary' })
136
+ ]
137
+ })
138
+ ]
139
+ };
140
+ ```
141
+
142
+ ## Step 7b: Add form validation with handles
143
+
144
+ The contact form above works, but there's no feedback when the user submits. Use `o.slots` for a status message and `o.handle` for show/clear methods -- no full re-render needed, so the form inputs keep their values and focus:
145
+
146
+ ```javascript
147
+ var contactForm = {
148
+ t: 'section', a: { id: 'contact', style: 'padding: 3rem 1rem; max-width: 600px; margin: 0 auto' },
149
+ c: [
150
+ { t: 'h2', c: 'Contact Us' },
151
+ { t: 'div', a: { class: 'status', style: 'display:none' }, c: '' },
152
+ bw.makeForm({
153
+ children: [
154
+ bw.makeFormGroup({ label: 'Name', input: bw.makeInput({ type: 'text', placeholder: 'Jane Smith' }) }),
155
+ bw.makeFormGroup({ label: 'Email', input: bw.makeInput({ type: 'email', placeholder: 'jane@example.com' }) }),
156
+ bw.makeFormGroup({ label: 'Message', input: bw.makeTextarea({ placeholder: 'How can we help?' }) }),
157
+ bw.makeButton({ text: 'Send Message', type: 'submit', variant: 'primary' })
158
+ ],
159
+ onsubmit: function(e) {
160
+ e.preventDefault();
161
+ // Access el.bw via the mounted element
162
+ var el = e.target.closest('[class*="bw_uuid"]') || e.target.parentElement;
163
+ if (el && el.bw) {
164
+ el.bw.showStatus('Message sent! We will reply within 24 hours.');
165
+ }
166
+ }
167
+ })
168
+ ],
169
+ o: {
170
+ slots: { status: '.status' },
171
+ handle: {
172
+ showStatus: function(el, msg) {
173
+ var s = el.querySelector('.status');
174
+ s.style.display = 'block';
175
+ s.textContent = msg;
176
+ s.style.cssText = 'padding:0.75rem;border-radius:8px;background:#d4edda;color:#155724;margin-bottom:1rem';
177
+ },
178
+ clearStatus: function(el) {
179
+ var s = el.querySelector('.status');
180
+ s.style.display = 'none';
181
+ s.textContent = '';
182
+ }
183
+ }
184
+ }
185
+ };
186
+ var formEl = bw.mount('#contact-wrapper', contactForm);
187
+ // Can also call from outside: formEl.bw.showStatus('Saved!');
188
+ ```
189
+
190
+ The key insight: `o.handle` methods update just the status div. The form inputs -- and any text the user has typed -- are untouched. This is why handles exist: targeted updates without re-render side effects.
191
+
192
+ ## Step 8: Compose and render
193
+
194
+ Now combine everything into one `bw.DOM()` call:
195
+
196
+ ```javascript
197
+ bw.DOM('#app', {
198
+ t: 'div', a: { class: 'brand' }, // theme scope class
199
+ c: [
200
+ nav,
201
+ hero,
202
+ { t: 'section', a: { id: 'features', style: 'padding: 3rem 1rem' }, c: [
203
+ { t: 'h2', a: { style: 'text-align: center' }, c: 'Features' },
204
+ features
205
+ ]},
206
+ pricing,
207
+ contact,
208
+ { t: 'footer', a: { style: 'text-align: center; padding: 2rem; color: #666' },
209
+ c: '2026 Acme Inc. Built with bitwrench.' }
210
+ ]
211
+ });
212
+ ```
213
+
214
+ One function call, one mount point, one render. The entire page is described as a tree of plain objects.
215
+
216
+ ## Step 9: Add custom CSS
217
+
218
+ Use `bw.css()` for page-specific styles:
219
+
220
+ ```javascript
221
+ bw.injectCSS(bw.css({
222
+ '.brand .bw-hero': {
223
+ 'text-align': 'center',
224
+ 'background': 'linear-gradient(135deg, #2563eb 0%, #7c3aed 100%)',
225
+ 'color': '#fff',
226
+ 'padding': '5rem 2rem'
227
+ },
228
+ '.brand footer': {
229
+ 'border-top': '1px solid #e5e7eb'
230
+ }
231
+ }));
232
+ ```
233
+
234
+ ## The complete file
235
+
236
+ Putting it all together, the full `index.html` is about 120 lines of JavaScript. No npm, no build tool, no framework CLI. Just one HTML file and one `<script>` tag.
237
+
238
+ ## Converting to a static site with bwcli
239
+
240
+ You can also write content in Markdown and convert it:
241
+
242
+ ```bash
243
+ npm install -g bitwrench
244
+ bwcli README.md --theme ocean --standalone -o index.html
245
+ ```
246
+
247
+ This produces a self-contained HTML file with the ocean theme baked in — works offline, no CDN needed.
248
+
249
+ ## Next steps
250
+
251
+ - [Component Library](component-library.md) -- all 50+ `make*()` functions
252
+ - [Theming](theming.md) -- customize colors, spacing, and radius
253
+ - [State Management](state-management.md) -- add interactivity with `o.state` + `o.render`
254
+ - [Routing](routing.md) -- turn this into a multi-page SPA with `bw.router()`
255
+ - [bwserve](bwserve.md) -- server-driven dynamic pages
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bitwrench",
3
- "version": "2.0.22",
3
+ "version": "2.0.23",
4
4
  "description": "A library for javascript UI functions.",
5
5
  "main": "./dist/bitwrench.umd.js",
6
6
  "repository": {
@@ -13,7 +13,8 @@
13
13
  "author": "manu a. chatterjee <deftio@deftio.com> (https://deftio.com/)",
14
14
  "license": "BSD-2-Clause",
15
15
  "bin": {
16
- "bwcli": "./bin/bwcli.js"
16
+ "bwcli": "./bin/bwcli.js",
17
+ "bwmcp": "./bin/bwmcp.js"
17
18
  },
18
19
  "type": "module",
19
20
  "module": "./dist/bitwrench.esm.js",
@@ -36,16 +37,21 @@
36
37
  "./bwserve": {
37
38
  "import": "./dist/bwserve.esm.js",
38
39
  "require": "./dist/bwserve.cjs.js"
40
+ },
41
+ "./mcp": {
42
+ "import": "./src/mcp/server.js"
39
43
  }
40
44
  },
41
45
  "types": "./dist/bitwrench.d.ts",
42
46
  "files": [
43
47
  "dist/*.js",
48
+ "dist/*.js.gz",
44
49
  "dist/*.css",
45
50
  "dist/*.json",
46
51
  "dist/*.d.ts",
47
52
  "bin/",
48
53
  "src/",
54
+ "docs/",
49
55
  "README.md",
50
56
  "LICENSE.txt"
51
57
  ],
@@ -95,7 +101,7 @@
95
101
  "update_rm": "echo 'DEPRECATED: use build:index instead'",
96
102
  "cleanbuild": "npm run clean && npm run build && npm run build:generated",
97
103
  "oldtest": "./node_modules/mocha/bin/mocha test/bitwrench_test.js --reporter spec",
98
- "test": "c8 --reporter=text mocha ./test/bitwrench_ci.js ./test/bitwrench_test_coverage.js ./test/bitwrench_test_pubsub.js ./test/bitwrench_test_theme.js ./test/bitwrench_test_nodemap.js ./test/bitwrench_test_components.js ./test/bitwrench_test_coverage_gaps.js ./test/bitwrench_test_bwserve.js ./test/bitwrench_test_attach.js ./test/bitwrench_test_serve.js ./test/bitwrench_test_code_edit.js ./test/bitwrench_test_html_page.js ./test/bitwrench_test_util_css.js ./test/bitwrench_test_handle.js ./test/bitwrench_test_debug.js ./test/bitwrench_test_router.js -r jsdom-global/register",
104
+ "test": "c8 --reporter=text mocha ./test/bitwrench_ci.js ./test/bitwrench_test_coverage.js ./test/bitwrench_test_pubsub.js ./test/bitwrench_test_theme.js ./test/bitwrench_test_nodemap.js ./test/bitwrench_test_components.js ./test/bitwrench_test_coverage_gaps.js ./test/bitwrench_test_bwserve.js ./test/bitwrench_test_attach.js ./test/bitwrench_test_serve.js ./test/bitwrench_test_code_edit.js ./test/bitwrench_test_html_page.js ./test/bitwrench_test_util_css.js ./test/bitwrench_test_handle.js ./test/bitwrench_test_debug.js ./test/bitwrench_test_router.js ./test/bitwrench_test_mcp_transport.js ./test/bitwrench_test_mcp_server.js ./test/bitwrench_test_mcp_tools.js ./test/bitwrench_test_mcp_knowledge.js -r jsdom-global/register",
99
105
  "test:bwserve": "mocha ./test/bitwrench_test_bwserve.js -r jsdom-global/register",
100
106
  "test:attach": "mocha ./test/bitwrench_test_attach.js -r jsdom-global/register",
101
107
  "test:serve": "mocha ./test/bitwrench_test_serve.js -r jsdom-global/register --exit",
@@ -117,6 +123,8 @@
117
123
  "test:router": "mocha ./test/bitwrench_test_router.js -r jsdom-global/register",
118
124
  "test:code-edit": "mocha ./test/bitwrench_test_code_edit.js -r jsdom-global/register",
119
125
  "test:html-page": "mocha ./test/bitwrench_test_html_page.js -r jsdom-global/register",
126
+ "test:mcp": "mocha ./test/bitwrench_test_mcp_transport.js ./test/bitwrench_test_mcp_server.js ./test/bitwrench_test_mcp_tools.js ./test/bitwrench_test_mcp_knowledge.js -r jsdom-global/register --exit",
127
+ "test:mcp:e2e": "mocha ./test/bitwrench_test_mcp_e2e.js --exit --timeout 15000",
120
128
  "test:e2e": "playwright test",
121
129
  "test:e2e:headed": "playwright test --headed",
122
130
  "test:e2e:debug": "playwright test --debug",
package/readme.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta name="generator" content="bitwrench v2.0.22">
6
+ <meta name="generator" content="bitwrench v2.0.23">
7
7
  <title>bitwrench.js - README</title>
8
8
  <link rel="icon" type="image/x-icon" href="images/favicon.ico">
9
9
  <script src="dist/bitwrench.umd.min.js"></script>
@@ -84,14 +84,15 @@ var page = {
84
84
 
85
85
  bw.DOM(&#39;#app&#39;, page); // -&gt; live DOM
86
86
  bw.html(page); // -&gt; HTML string (Node.js, emails, SSR)</code></pre><p>Each object has four keys: <strong class="quikdown-strong">t</strong> (tag), <strong class="quikdown-strong">a</strong> (attributes), <strong class="quikdown-strong">c</strong> (content), <strong class="quikdown-strong">o</strong> (options for state/lifecycle). Nest them, loop them, compose them -- it&#39;s just JavaScript.</p><h3 class="quikdown-h3">Why bitwrench?</h3>
87
- <strong class="quikdown-strong">One file, everywhere.</strong> At ~38KB gzipped with zero dependencies, bitwrench runs on anything with a browser -- phones, tablets, Raspberry Pi, even ESP32 microcontrollers. The device serves a single HTML page and pushes data as JSON; bitwrench handles all rendering, styling, and state on the client. No Node.js, no build step, no internet connection required.</p><p>Structure, styling, state, and server rendering are all handled as JavaScript objects:</p><ul class="quikdown-ul">
87
+ <strong class="quikdown-strong">One file, everywhere.</strong> At ~40KB gzipped with zero dependencies, bitwrench runs on anything with a browser -- phones, tablets, Raspberry Pi, even ESP32 microcontrollers. The device serves a single HTML page and pushes data as JSON; bitwrench handles all rendering, styling, and state on the client. No Node.js, no build step, no internet connection required.</p><p>Structure, styling, state, and server rendering are all handled as JavaScript objects:</p><ul class="quikdown-ul">
88
88
  <li class="quikdown-li"><strong class="quikdown-strong">No build toolchain</strong> -- works with a <code class="quikdown-code">&lt;script&gt;</code> tag</li>
89
89
  <li class="quikdown-li"><strong class="quikdown-strong">50+ ready-made components</strong> -- buttons, tables, modals, forms, charts, toasts -- one <code class="quikdown-code">make*()</code> call each, returns a composable TACO</li>
90
90
  <li class="quikdown-li"><strong class="quikdown-strong">CSS from JavaScript</strong> -- <code class="quikdown-code">bw.css()</code> generates stylesheets, <code class="quikdown-code">bw.s()</code> composes inline styles, <code class="quikdown-code">bw.loadStyles()</code> derives a complete design system from 2 seed colors</li>
91
91
  <li class="quikdown-li"><strong class="quikdown-strong">Reactive state</strong> -- <code class="quikdown-code">o.state</code> + <code class="quikdown-code">o.render</code> + <code class="quikdown-code">bw.update()</code> for stateful components; <code class="quikdown-code">bw.pub()</code>/<code class="quikdown-code">bw.sub()</code> for cross-component messaging</li>
92
92
  <li class="quikdown-li"><strong class="quikdown-strong">Dual rendering</strong> -- same object renders to live DOM (<code class="quikdown-code">bw.DOM()</code>) or HTML string (<code class="quikdown-code">bw.html()</code>) for SSR, emails, or static sites</li>
93
- <li class="quikdown-li"><strong class="quikdown-strong">Server-driven UI</strong> -- push UI updates from any backend (Python, C, Rust, Go) over SSE; <code class="quikdown-code">client.screenshot()</code> captures the page back as PNG/JPEG</li>
93
+ <li class="quikdown-li"><strong class="quikdown-strong">Server-driven UI</strong> -- push UI updates from any backend (Python, C, Rust, Go) over SSE via the biwrench bwserve protocol; <code class="quikdown-code">client.screenshot()</code> captures the page back as PNG/JPEG</li>
94
94
  <li class="quikdown-li"><strong class="quikdown-strong">CLI</strong> -- <code class="quikdown-code">bwcli</code> converts Markdown, HTML, and JSON to styled standalone pages</li>
95
+ <li class="quikdown-li"><strong class="quikdown-strong">Debug tools</strong> -- live client and server debugging with remote incremental inspect, screenshots, and state updates</li>
95
96
  <li class="quikdown-li"><strong class="quikdown-strong">Utilities</strong> -- color interpolation, random data, lorem ipsum, cookies, URL params, file I/O</li>
96
97
  </ul><h3 class="quikdown-h3">Coming from other Frameworks</h3>
97
98
  <p>Bitwrench uses JavaScript equivalents for most forms of front-end development. Here is a quick mapping (see the <a class="quikdown-a" href="docs/README.md">docs</a> and <a class="quikdown-a" href="docs/thinking-in-bitwrench.md">Thinking in Bitwrench</a> for more details).</p><table class="quikdown-table">
@@ -381,7 +382,7 @@ curl -X POST http://localhost:9000 -d &#39;{&quot;type&quot;:&quot;patch&quot;,&
381
382
  <li class="quikdown-li"><a class="quikdown-a" href="examples/client-server/">bwserve Counter</a> -- server-driven UI demo</li>
382
383
  <li class="quikdown-li"><a class="quikdown-a" href="examples/llm-chat/">LLM Chat</a> -- streaming chat via bwserve + Ollama/OpenAI</li>
383
384
  </ul><h2 class="quikdown-h2">FAQ</h2>
384
- <strong class="quikdown-strong">Is this a framework?</strong> -- No. Bitwrench is a library (~38KB gzipped). No lifecycle to learn, no project structure to follow. Import it, call functions, done.</p><p><strong class="quikdown-strong">How does bitwrench compare to React/Vue?</strong> -- They solve different problems at different scales. React and Vue provide a component model, virtual DOM, and ecosystem for large team-built SPAs. Bitwrench provides rendering and state primitives in a single file with no build step, aimed at single-page tools, dashboards, embedded devices, and server-driven UIs. They coexist fine -- use whichever fits the job.</p><p><strong class="quikdown-strong">How does CSS work?</strong> -- Bitwrench doesn&#39;t own your CSS. Use any external stylesheet, Tailwind, or CSS file you want -- bitwrench doesn&#39;t interfere. On top of that, <code class="quikdown-code">bw.css()</code> generates CSS from JS objects (with <code class="quikdown-code">@media</code>, <code class="quikdown-code">@keyframes</code>, pseudo-classes), <code class="quikdown-code">bw.s()</code> composes inline style objects, and <code class="quikdown-code">bw.loadStyles()</code> derives a complete design system from 2 seed colors. You can use all three together or none at all.</p><p><strong class="quikdown-strong">What&#39;s the difference between <code class="quikdown-code">bw.DOM()</code> and <code class="quikdown-code">bw.html()</code>?</strong> -- Same TACO input, two outputs. <code class="quikdown-code">bw.DOM(&#39;#app&#39;, taco)</code> mounts live DOM elements in a browser. <code class="quikdown-code">bw.html(taco)</code> returns an HTML string -- use it in Node.js scripts, email generators, static site builds, or anywhere you need markup without a browser. One object format, two rendering modes.</p><p><strong class="quikdown-strong">What is bwserve?</strong> -- bwserve lets any server push UI updates to a browser over SSE. The server sends TACO objects as JSON; the browser renders them. It&#39;s language-agnostic -- the server can be Python, Go, Rust, C, or a shell script. Anything that can write JSON to an HTTP response can drive a bitwrench UI. See the <a class="quikdown-a" href="docs/bwserve.md">bwserve docs</a>.</p><p><strong class="quikdown-strong">Can I use bitwrench on embedded devices?</strong> -- Yes -- this is a primary use case. An ESP32 or Raspberry Pi serves one HTML page with bitwrench loaded, then pushes sensor data as JSON patches over SSE. The device never generates HTML. See the <a class="quikdown-a" href="docs/tutorial-embedded.md">ESP32 tutorial</a>.</p><p><strong class="quikdown-strong">Can I use it with TypeScript?</strong> -- Yes. Type declarations are included. TACO objects are plain JSON-compatible objects that TypeScript infers naturally.</p><p><strong class="quikdown-strong">What about accessibility?</strong> -- BCCL components emit semantic HTML with ARIA attributes where applicable. You can add any <code class="quikdown-code">aria-*</code> attribute via <code class="quikdown-code">a: { &#39;aria-label&#39;: &#39;...&#39; }</code>.</p><h2 class="quikdown-h2">Development</h2>
385
+ <strong class="quikdown-strong">Is this a framework?</strong> -- No. Bitwrench is a library (~40KB gzipped). No lifecycle to learn, no project structure to follow. Import it, call functions, done.</p><p><strong class="quikdown-strong">How does bitwrench compare to React/Vue?</strong> -- They solve different problems at different scales. React and Vue provide a component model, virtual DOM, and ecosystem for large team-built SPAs. Bitwrench provides rendering and state primitives in a single file with no build step, aimed at single-page tools, dashboards, embedded devices, and server-driven UIs. They coexist fine -- use whichever fits the job.</p><p><strong class="quikdown-strong">How does CSS work?</strong> -- Bitwrench doesn&#39;t own your CSS. Use any external stylesheet, Tailwind, or CSS file you want -- bitwrench doesn&#39;t interfere. On top of that, <code class="quikdown-code">bw.css()</code> generates CSS from JS objects (with <code class="quikdown-code">@media</code>, <code class="quikdown-code">@keyframes</code>, pseudo-classes), <code class="quikdown-code">bw.s()</code> composes inline style objects, and <code class="quikdown-code">bw.loadStyles()</code> derives a complete design system from 2 seed colors. You can use all three together or none at all.</p><p><strong class="quikdown-strong">What&#39;s the difference between <code class="quikdown-code">bw.DOM()</code> and <code class="quikdown-code">bw.html()</code>?</strong> -- Same TACO input, two outputs. <code class="quikdown-code">bw.DOM(&#39;#app&#39;, taco)</code> mounts live DOM elements in a browser. <code class="quikdown-code">bw.html(taco)</code> returns an HTML string -- use it in Node.js scripts, email generators, static site builds, or anywhere you need markup without a browser. One object format, two rendering modes.</p><p><strong class="quikdown-strong">What is bwserve?</strong> -- bwserve lets any server push UI updates to a browser over SSE. The server sends TACO objects as JSON; the browser renders them. It&#39;s language-agnostic -- the server can be Python, Go, Rust, C, or a shell script. Anything that can write JSON to an HTTP response can drive a bitwrench UI. See the <a class="quikdown-a" href="docs/bwserve.md">bwserve docs</a>.</p><p><strong class="quikdown-strong">Can I use bitwrench on embedded devices?</strong> -- Yes -- this is a primary use case. An ESP32 or Raspberry Pi serves one HTML page with bitwrench loaded, then pushes sensor data as JSON patches over SSE. The device never generates HTML. See the <a class="quikdown-a" href="docs/tutorial-embedded.md">ESP32 tutorial</a>.</p><p><strong class="quikdown-strong">Can I use it with TypeScript?</strong> -- Yes. Type declarations are included. TACO objects are plain JSON-compatible objects that TypeScript infers naturally.</p><p><strong class="quikdown-strong">What about accessibility?</strong> -- BCCL components emit semantic HTML with ARIA attributes where applicable. You can add any <code class="quikdown-code">aria-*</code> attribute via <code class="quikdown-code">a: { &#39;aria-label&#39;: &#39;...&#39; }</code>.</p><h2 class="quikdown-h2">Development</h2>
385
386
  <p><pre class="quikdown-pre"><code class="language-bash">npm install # install dev dependencies
386
387
  npm run build # build all dist formats (UMD, ESM, CJS, ES5)
387
388
  npm test # run unit tests (1400+ tests, 96% coverage)
@@ -0,0 +1,231 @@
1
+ /**
2
+ * MCP knowledge tools -- serve documentation as tool results.
3
+ *
4
+ * Knowledge tools read .md files from docs/ at call time (no caching,
5
+ * always fresh). Section/component filtering uses simple heading parsing.
6
+ *
7
+ * @module mcp/knowledge
8
+ */
9
+
10
+ import { readFileSync } from 'fs';
11
+ import { resolve, dirname } from 'path';
12
+ import { fileURLToPath } from 'url';
13
+
14
+ var __dirname = dirname(fileURLToPath(import.meta.url));
15
+ var DOCS_DIR = resolve(__dirname, '../../docs');
16
+
17
+ // Section name -> heading prefix mapping for bitwrench_guide
18
+ var GUIDE_SECTIONS = {
19
+ 'taco': 'Step 2: Understand TACO',
20
+ 'levels': 'Step 3: Three Levels',
21
+ 'events': 'Step 4: Events',
22
+ 'css': 'Step 5: CSS and Theming',
23
+ 'components': 'Step 6: BCCL Components',
24
+ 'bwserve': 'Step 8: bwserve',
25
+ 'routing': 'Step 9: Client-Side Routing',
26
+ 'api-reference': 'Core API Quick Reference',
27
+ 'rules': 'Key Rules Summary'
28
+ };
29
+
30
+ /**
31
+ * Extract a section from markdown content by ## heading.
32
+ * Returns text from the matching ## heading to the next ## heading (or EOF).
33
+ */
34
+ function extractSection(content, heading) {
35
+ var lines = content.split('\n');
36
+ var start = -1;
37
+ var end = lines.length;
38
+ for (var i = 0; i < lines.length; i++) {
39
+ var line = lines[i];
40
+ if (start === -1) {
41
+ if (line.startsWith('## ') && line.indexOf(heading) >= 0) {
42
+ start = i;
43
+ }
44
+ } else if (line.startsWith('## ')) {
45
+ end = i;
46
+ break;
47
+ }
48
+ }
49
+ if (start === -1) return null;
50
+ return lines.slice(start, end).join('\n').trim();
51
+ }
52
+
53
+ /**
54
+ * Extract a component section from component-library.md by ### heading.
55
+ */
56
+ function extractComponent(content, name) {
57
+ var lines = content.split('\n');
58
+ var start = -1;
59
+ var end = lines.length;
60
+ for (var i = 0; i < lines.length; i++) {
61
+ var line = lines[i];
62
+ if (start === -1) {
63
+ if (line.startsWith('### ') && line.indexOf(name) >= 0) {
64
+ start = i;
65
+ }
66
+ } else if (line.startsWith('### ') || line.startsWith('## ')) {
67
+ end = i;
68
+ break;
69
+ }
70
+ }
71
+ if (start === -1) return null;
72
+ return lines.slice(start, end).join('\n').trim();
73
+ }
74
+
75
+ /**
76
+ * Read a doc file. Returns content string or error message.
77
+ */
78
+ function readDoc(filename) {
79
+ try {
80
+ return readFileSync(resolve(DOCS_DIR, filename), 'utf8');
81
+ } catch (e) {
82
+ return 'Error: could not read ' + filename + ' (' + e.code + ')';
83
+ }
84
+ }
85
+
86
+ // -- Tool definitions --
87
+
88
+ export var knowledgeToolDefs = [
89
+ {
90
+ name: 'bitwrench_start_here',
91
+ title: 'Start Here -- Bitwrench Quick Orientation',
92
+ description: 'IMPORTANT: Call this tool FIRST before using any other bitwrench tools. Returns a quick orientation: what bitwrench is, the TACO format, your workflow for building UI, and which other tools to call for deeper knowledge.',
93
+ inputSchema: { type: 'object', properties: {} }
94
+ },
95
+ {
96
+ name: 'bitwrench_guide',
97
+ title: 'Bitwrench Developer Guide',
98
+ description: 'Complete bitwrench developer guide covering TACO format, component composition, layout patterns, theming, and workflow. Call this to learn how to use bitwrench effectively. Read this guide, then use the component and utility tools.',
99
+ inputSchema: {
100
+ type: 'object',
101
+ properties: {
102
+ section: {
103
+ type: 'string',
104
+ description: 'Optional: return only a specific section. Omit for full guide.',
105
+ enum: ['taco', 'levels', 'events', 'css', 'components', 'bwserve', 'routing', 'api-reference', 'rules']
106
+ }
107
+ }
108
+ }
109
+ },
110
+ {
111
+ name: 'bitwrench_components',
112
+ title: 'Component Library Reference',
113
+ description: 'Complete reference for all bitwrench make*() components. Call this when you need to know the exact props, variants, and options for a specific component. Returns the full component catalog with examples.',
114
+ inputSchema: {
115
+ type: 'object',
116
+ properties: {
117
+ component: {
118
+ type: 'string',
119
+ description: "Optional: return docs for a specific component only (e.g. 'makeCard', 'makeTable', 'makeAccordion'). Omit for complete catalog."
120
+ }
121
+ }
122
+ }
123
+ },
124
+ {
125
+ name: 'bitwrench_server_guide',
126
+ title: 'Server-Driven UI Guide',
127
+ description: 'Tutorial for building server-driven UI with bwserve. Covers: SSE streaming, replace/patch/append protocol, data-bw-action buttons, live metrics, screenshots. Call this when building real-time or server-pushed interfaces.',
128
+ inputSchema: { type: 'object', properties: {} }
129
+ },
130
+ {
131
+ name: 'bitwrench_themes',
132
+ title: 'Theme and Color Reference',
133
+ description: 'Reference for bitwrench theming: 12 built-in presets (teal, ocean, sunset, forest, slate, rose, indigo, amber, emerald, nord, coral, midnight), custom palette configuration, color utilities.',
134
+ inputSchema: { type: 'object', properties: {} }
135
+ }
136
+ ];
137
+
138
+ // -- Tool handlers --
139
+
140
+ var START_HERE_TEXT = [
141
+ 'BITWRENCH QUICK ORIENTATION',
142
+ '============================',
143
+ '',
144
+ 'Bitwrench is a zero-dependency JS UI library (~40KB gzipped). You',
145
+ 'generate UI by composing TACO objects -- plain JSON:',
146
+ '',
147
+ " {t: 'div', a: {class: 'bw_card'}, c: 'Hello'}",
148
+ ' ^tag ^attributes ^content (string, TACO, or array)',
149
+ '',
150
+ 'YOUR WORKFLOW:',
151
+ '1. Call bitwrench_guide to learn TACO format, layout, and composition',
152
+ '2. Call bitwrench_components to look up props for specific components',
153
+ '3. Call make_card, make_table, make_hero, etc. to build TACO components',
154
+ '4. Nest TACOs into a layout using the grid: bw_container > bw_row > bw_col',
155
+ '5. Call build_page with a theme to produce a complete standalone .html file',
156
+ '',
157
+ 'KEY RULES:',
158
+ '- Every make*() tool returns a TACO object, NOT HTML',
159
+ "- Compose by nesting TACOs in the 'c' field: {t:'div', c: [taco1, taco2]}",
160
+ '- Grid layout:',
161
+ " {t:'div', a:{class:'bw_container'}, c:[",
162
+ " {t:'div', a:{class:'bw_row'}, c:[",
163
+ " {t:'div', a:{class:'bw_col'}, c:[ <your content> ]}",
164
+ ' ]}',
165
+ ' ]}',
166
+ "- Themes: pass theme:'ocean' to build_page (also: forest, sunset,",
167
+ ' midnight, slate, rose, indigo, amber, emerald, nord, coral, teal)',
168
+ '- Call render_taco to convert any TACO to an HTML string',
169
+ '- Call build_page to get a complete standalone .html file (works offline)',
170
+ '',
171
+ 'OTHER KNOWLEDGE TOOLS (call as needed):',
172
+ '- bitwrench_guide: Full tutorial (TACO format, 3 levels, events, CSS,',
173
+ ' components, bwserve, routing, API reference)',
174
+ '- bitwrench_components: Props reference for all 47+ make*() components',
175
+ '- bitwrench_server_guide: bwserve tutorial (SSE streaming, live UI)',
176
+ '- bitwrench_themes: Theme presets, custom palettes, color utilities'
177
+ ].join('\n');
178
+
179
+ export var knowledgeHandlers = {
180
+ bitwrench_start_here: function() {
181
+ return { content: [{ type: 'text', text: START_HERE_TEXT }] };
182
+ },
183
+
184
+ bitwrench_guide: function(args) {
185
+ var content = readDoc('llm-bitwrench-guide.md');
186
+ if (args && args.section) {
187
+ var heading = GUIDE_SECTIONS[args.section];
188
+ if (!heading) {
189
+ return {
190
+ content: [{ type: 'text', text: 'Unknown section: ' + args.section + '. Valid: ' + Object.keys(GUIDE_SECTIONS).join(', ') }],
191
+ isError: true
192
+ };
193
+ }
194
+ var section = extractSection(content, heading);
195
+ if (!section) {
196
+ return {
197
+ content: [{ type: 'text', text: 'Section not found in guide: ' + heading }],
198
+ isError: true
199
+ };
200
+ }
201
+ content = section;
202
+ }
203
+ return { content: [{ type: 'text', text: content }] };
204
+ },
205
+
206
+ bitwrench_components: function(args) {
207
+ var content = readDoc('component-library.md');
208
+ if (args && args.component) {
209
+ var section = extractComponent(content, args.component);
210
+ if (!section) {
211
+ return {
212
+ content: [{ type: 'text', text: 'Component not found: ' + args.component }],
213
+ isError: true
214
+ };
215
+ }
216
+ content = section;
217
+ }
218
+ return { content: [{ type: 'text', text: content }] };
219
+ },
220
+
221
+ bitwrench_server_guide: function() {
222
+ return { content: [{ type: 'text', text: readDoc('tutorial-bwserve.md') }] };
223
+ },
224
+
225
+ bitwrench_themes: function() {
226
+ return { content: [{ type: 'text', text: readDoc('theming.md') }] };
227
+ }
228
+ };
229
+
230
+ // Exported for testing
231
+ export { extractSection, extractComponent, readDoc, GUIDE_SECTIONS, DOCS_DIR };