@weavetab/mcp 2.5.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. package/AGENTS.md +48 -0
  2. package/ARCHITECTURE.md +590 -0
  3. package/LICENSE +631 -0
  4. package/README.md +909 -0
  5. package/SECURITY.md +196 -0
  6. package/TROUBLESHOOTING.md +365 -0
  7. package/dist/anticaptcha/detector.d.ts +49 -0
  8. package/dist/anticaptcha/detector.js +465 -0
  9. package/dist/anticaptcha/integration.d.ts +36 -0
  10. package/dist/anticaptcha/integration.js +123 -0
  11. package/dist/anticaptcha/solver.d.ts +27 -0
  12. package/dist/anticaptcha/solver.js +552 -0
  13. package/dist/audit/logger.d.ts +13 -0
  14. package/dist/audit/logger.js +177 -0
  15. package/dist/audit/telemetry.d.ts +36 -0
  16. package/dist/audit/telemetry.js +162 -0
  17. package/dist/cdp/bridge.d.ts +16 -0
  18. package/dist/cdp/bridge.js +826 -0
  19. package/dist/cdp/confirm.d.ts +26 -0
  20. package/dist/cdp/confirm.js +79 -0
  21. package/dist/cdp/connector.d.ts +37 -0
  22. package/dist/cdp/connector.js +661 -0
  23. package/dist/cdp/extension.d.ts +36 -0
  24. package/dist/cdp/extension.js +118 -0
  25. package/dist/cdp/finder.d.ts +1 -0
  26. package/dist/cdp/finder.js +2 -0
  27. package/dist/cdp/helpers.d.ts +11 -0
  28. package/dist/cdp/helpers.js +195 -0
  29. package/dist/cdp/label_cache.d.ts +12 -0
  30. package/dist/cdp/label_cache.js +51 -0
  31. package/dist/cdp/lock.d.ts +33 -0
  32. package/dist/cdp/lock.js +206 -0
  33. package/dist/cdp/omni_broker.d.ts +17 -0
  34. package/dist/cdp/omni_broker.js +119 -0
  35. package/dist/cdp/profiles.d.ts +1 -0
  36. package/dist/cdp/profiles.js +87 -0
  37. package/dist/cdp/pruner.d.ts +41 -0
  38. package/dist/cdp/pruner.js +263 -0
  39. package/dist/cdp/ref_cache.d.ts +101 -0
  40. package/dist/cdp/ref_cache.js +234 -0
  41. package/dist/cdp/retry.d.ts +5 -0
  42. package/dist/cdp/retry.js +39 -0
  43. package/dist/cdp/retry_enhanced.d.ts +44 -0
  44. package/dist/cdp/retry_enhanced.js +102 -0
  45. package/dist/cdp/security.d.ts +50 -0
  46. package/dist/cdp/security.js +237 -0
  47. package/dist/cdp/verify.d.ts +39 -0
  48. package/dist/cdp/verify.js +143 -0
  49. package/dist/cdp/walker.d.ts +91 -0
  50. package/dist/cdp/walker.js +896 -0
  51. package/dist/cdp/walker.test.d.ts +2 -0
  52. package/dist/cdp/walker.test.js +172 -0
  53. package/dist/cdp/websocket_transport.d.ts +15 -0
  54. package/dist/cdp/websocket_transport.js +118 -0
  55. package/dist/cli/plugin.d.ts +9 -0
  56. package/dist/cli/plugin.js +1134 -0
  57. package/dist/cli/updater.d.ts +1 -0
  58. package/dist/cli/updater.js +72 -0
  59. package/dist/config/loader.d.ts +120 -0
  60. package/dist/config/loader.js +704 -0
  61. package/dist/index.d.ts +2 -0
  62. package/dist/index.js +1248 -0
  63. package/dist/intelligence/hints.d.ts +11 -0
  64. package/dist/intelligence/hints.js +39 -0
  65. package/dist/intelligence/intent.d.ts +33 -0
  66. package/dist/intelligence/intent.js +171 -0
  67. package/dist/intelligence/sessionMemory.d.ts +66 -0
  68. package/dist/intelligence/sessionMemory.js +284 -0
  69. package/dist/intelligence/sessionMemory.test.d.ts +2 -0
  70. package/dist/intelligence/sessionMemory.test.js +62 -0
  71. package/dist/intelligence/trail.d.ts +64 -0
  72. package/dist/intelligence/trail.js +233 -0
  73. package/dist/intelligence/trail.test.d.ts +2 -0
  74. package/dist/intelligence/trail.test.js +110 -0
  75. package/dist/intelligence/vision.d.ts +24 -0
  76. package/dist/intelligence/vision.js +151 -0
  77. package/dist/lifecycle/mission_manager.d.ts +16 -0
  78. package/dist/lifecycle/mission_manager.js +44 -0
  79. package/dist/overlay/bubble.d.ts +16 -0
  80. package/dist/overlay/bubble.js +37 -0
  81. package/dist/overlay/ghost.d.ts +35 -0
  82. package/dist/overlay/ghost.js +508 -0
  83. package/dist/overlay/injector.d.ts +22 -0
  84. package/dist/overlay/injector.js +198 -0
  85. package/dist/plugin/interface.d.ts +134 -0
  86. package/dist/plugin/interface.js +1 -0
  87. package/dist/plugin/loader.d.ts +18 -0
  88. package/dist/plugin/loader.js +155 -0
  89. package/dist/plugin/registry.d.ts +50 -0
  90. package/dist/plugin/registry.js +234 -0
  91. package/dist/security/blacklist.d.ts +24 -0
  92. package/dist/security/blacklist.js +80 -0
  93. package/dist/security/filter.d.ts +2 -0
  94. package/dist/security/filter.js +20 -0
  95. package/dist/security/guard.d.ts +8 -0
  96. package/dist/security/guard.js +35 -0
  97. package/dist/security/ratelimit.d.ts +11 -0
  98. package/dist/security/ratelimit.js +57 -0
  99. package/dist/security/secrets.d.ts +75 -0
  100. package/dist/security/secrets.js +365 -0
  101. package/dist/sensors/actionability.d.ts +81 -0
  102. package/dist/sensors/actionability.js +303 -0
  103. package/dist/sensors/guard.d.ts +25 -0
  104. package/dist/sensors/guard.js +168 -0
  105. package/dist/sensors/mutations.d.ts +23 -0
  106. package/dist/sensors/mutations.js +93 -0
  107. package/dist/sensors/network.d.ts +67 -0
  108. package/dist/sensors/network.js +193 -0
  109. package/dist/sensors/operation_monitor.d.ts +80 -0
  110. package/dist/sensors/operation_monitor.js +203 -0
  111. package/dist/sensors/pacing.d.ts +44 -0
  112. package/dist/sensors/pacing.js +111 -0
  113. package/dist/sensors/thoughts.d.ts +2 -0
  114. package/dist/sensors/thoughts.js +59 -0
  115. package/dist/sensors/wait.d.ts +12 -0
  116. package/dist/sensors/wait.js +44 -0
  117. package/dist/server.d.ts +7 -0
  118. package/dist/server.js +1687 -0
  119. package/dist/state/agent.d.ts +36 -0
  120. package/dist/state/agent.js +101 -0
  121. package/dist/state/cache.d.ts +16 -0
  122. package/dist/state/cache.js +92 -0
  123. package/dist/state/cache.test.d.ts +2 -0
  124. package/dist/state/cache.test.js +76 -0
  125. package/dist/state/delta.d.ts +71 -0
  126. package/dist/state/delta.js +234 -0
  127. package/dist/state/delta.test.d.ts +2 -0
  128. package/dist/state/delta.test.js +279 -0
  129. package/dist/state/groups.d.ts +15 -0
  130. package/dist/state/groups.js +80 -0
  131. package/dist/state/session.d.ts +30 -0
  132. package/dist/state/session.js +155 -0
  133. package/dist/tools/accessibility.d.ts +14 -0
  134. package/dist/tools/accessibility.js +32 -0
  135. package/dist/tools/ask.d.ts +14 -0
  136. package/dist/tools/ask.js +49 -0
  137. package/dist/tools/automation.d.ts +36 -0
  138. package/dist/tools/automation.js +218 -0
  139. package/dist/tools/browser_detect.d.ts +13 -0
  140. package/dist/tools/browser_detect.js +73 -0
  141. package/dist/tools/burst.d.ts +35 -0
  142. package/dist/tools/burst.js +344 -0
  143. package/dist/tools/canvas.d.ts +25 -0
  144. package/dist/tools/canvas.js +132 -0
  145. package/dist/tools/captcha.d.ts +38 -0
  146. package/dist/tools/captcha.js +209 -0
  147. package/dist/tools/click.d.ts +36 -0
  148. package/dist/tools/click.js +561 -0
  149. package/dist/tools/click_and_wait.d.ts +33 -0
  150. package/dist/tools/click_and_wait.js +149 -0
  151. package/dist/tools/clipboard.d.ts +29 -0
  152. package/dist/tools/clipboard.js +279 -0
  153. package/dist/tools/console.d.ts +21 -0
  154. package/dist/tools/console.js +107 -0
  155. package/dist/tools/cookies.d.ts +67 -0
  156. package/dist/tools/cookies.js +121 -0
  157. package/dist/tools/design_extract.d.ts +109 -0
  158. package/dist/tools/design_extract.js +641 -0
  159. package/dist/tools/dialog.d.ts +24 -0
  160. package/dist/tools/dialog.js +109 -0
  161. package/dist/tools/drag.d.ts +15 -0
  162. package/dist/tools/drag.js +29 -0
  163. package/dist/tools/emulation.d.ts +33 -0
  164. package/dist/tools/emulation.js +69 -0
  165. package/dist/tools/eval.d.ts +20 -0
  166. package/dist/tools/eval.js +92 -0
  167. package/dist/tools/fill.d.ts +41 -0
  168. package/dist/tools/fill.js +667 -0
  169. package/dist/tools/find.d.ts +30 -0
  170. package/dist/tools/find.js +60 -0
  171. package/dist/tools/geo.d.ts +19 -0
  172. package/dist/tools/geo.js +29 -0
  173. package/dist/tools/github/analyze.d.ts +4 -0
  174. package/dist/tools/github/analyze.js +113 -0
  175. package/dist/tools/github/cache.d.ts +21 -0
  176. package/dist/tools/github/cache.js +28 -0
  177. package/dist/tools/github/index.d.ts +4 -0
  178. package/dist/tools/github/index.js +4 -0
  179. package/dist/tools/github/issues.d.ts +9 -0
  180. package/dist/tools/github/issues.js +88 -0
  181. package/dist/tools/github/pr.d.ts +5 -0
  182. package/dist/tools/github/pr.js +88 -0
  183. package/dist/tools/github/rateLimiter.d.ts +4 -0
  184. package/dist/tools/github/rateLimiter.js +46 -0
  185. package/dist/tools/github/read.d.ts +34 -0
  186. package/dist/tools/github/read.js +74 -0
  187. package/dist/tools/github/repoContext.d.ts +20 -0
  188. package/dist/tools/github/repoContext.js +129 -0
  189. package/dist/tools/highlight.d.ts +20 -0
  190. package/dist/tools/highlight.js +140 -0
  191. package/dist/tools/hover.d.ts +19 -0
  192. package/dist/tools/hover.js +57 -0
  193. package/dist/tools/inspect.d.ts +17 -0
  194. package/dist/tools/inspect.js +125 -0
  195. package/dist/tools/integration.test.d.ts +2 -0
  196. package/dist/tools/integration.test.js +96 -0
  197. package/dist/tools/key.d.ts +25 -0
  198. package/dist/tools/key.js +173 -0
  199. package/dist/tools/macro_compiler.d.ts +7 -0
  200. package/dist/tools/macro_compiler.js +82 -0
  201. package/dist/tools/mouse.d.ts +21 -0
  202. package/dist/tools/mouse.js +62 -0
  203. package/dist/tools/navigate.d.ts +16 -0
  204. package/dist/tools/navigate.js +188 -0
  205. package/dist/tools/network_intercept.d.ts +17 -0
  206. package/dist/tools/network_intercept.js +151 -0
  207. package/dist/tools/office/index.d.ts +9 -0
  208. package/dist/tools/office/index.js +7 -0
  209. package/dist/tools/office/list.d.ts +15 -0
  210. package/dist/tools/office/list.js +41 -0
  211. package/dist/tools/office/parse.d.ts +20 -0
  212. package/dist/tools/office/parse.js +172 -0
  213. package/dist/tools/pdf.d.ts +22 -0
  214. package/dist/tools/pdf.js +42 -0
  215. package/dist/tools/performance.d.ts +12 -0
  216. package/dist/tools/performance.js +47 -0
  217. package/dist/tools/performance_test.d.ts +70 -0
  218. package/dist/tools/performance_test.js +128 -0
  219. package/dist/tools/plan.d.ts +39 -0
  220. package/dist/tools/plan.js +161 -0
  221. package/dist/tools/pointer.d.ts +35 -0
  222. package/dist/tools/pointer.js +522 -0
  223. package/dist/tools/read.d.ts +30 -0
  224. package/dist/tools/read.js +488 -0
  225. package/dist/tools/recording.d.ts +45 -0
  226. package/dist/tools/recording.js +124 -0
  227. package/dist/tools/response.d.ts +129 -0
  228. package/dist/tools/response.js +5 -0
  229. package/dist/tools/scrape.d.ts +24 -0
  230. package/dist/tools/scrape.js +140 -0
  231. package/dist/tools/screenshot.d.ts +40 -0
  232. package/dist/tools/screenshot.js +79 -0
  233. package/dist/tools/scroll.d.ts +23 -0
  234. package/dist/tools/scroll.js +196 -0
  235. package/dist/tools/select.d.ts +13 -0
  236. package/dist/tools/select.js +217 -0
  237. package/dist/tools/snapshot.d.ts +27 -0
  238. package/dist/tools/snapshot.js +99 -0
  239. package/dist/tools/storage.d.ts +18 -0
  240. package/dist/tools/storage.js +29 -0
  241. package/dist/tools/tabs.d.ts +77 -0
  242. package/dist/tools/tabs.js +342 -0
  243. package/dist/tools/thought.d.ts +16 -0
  244. package/dist/tools/thought.js +79 -0
  245. package/dist/tools/type.d.ts +65 -0
  246. package/dist/tools/type.js +1061 -0
  247. package/dist/tools/type_secret.d.ts +23 -0
  248. package/dist/tools/type_secret.js +229 -0
  249. package/dist/tools/upload.d.ts +19 -0
  250. package/dist/tools/upload.js +103 -0
  251. package/dist/tools/video_compiler.d.ts +24 -0
  252. package/dist/tools/video_compiler.js +199 -0
  253. package/dist/tools/viewport.d.ts +44 -0
  254. package/dist/tools/viewport.js +230 -0
  255. package/dist/tools/wait.d.ts +19 -0
  256. package/dist/tools/wait.js +202 -0
  257. package/dist/tools/wait_for.d.ts +23 -0
  258. package/dist/tools/wait_for.js +30 -0
  259. package/dist/tools/windows.d.ts +22 -0
  260. package/dist/tools/windows.js +57 -0
  261. package/dist/ui/index.d.ts +1 -0
  262. package/dist/ui/index.js +12 -0
  263. package/docs/DEV_MODE.md +68 -0
  264. package/docs/DOCUMENTATION.md +532 -0
  265. package/docs/PLUGINS.md +538 -0
  266. package/docs/TOOLS.md +104 -0
  267. package/docs/dev_plugin.md +310 -0
  268. package/ext-dist/background.js +467 -0
  269. package/ext-dist/content.js +3089 -0
  270. package/ext-dist/dashboard.html +583 -0
  271. package/ext-dist/hud/hud.js +73 -0
  272. package/ext-dist/hud/index.html +20 -0
  273. package/ext-dist/manifest.json +77 -0
  274. package/ext-dist/sidepanel/sidepanel.js +25 -0
  275. package/ext-dist/sidepanel.html +547 -0
  276. package/ext-dist/styles.css +218 -0
  277. package/icon.png +0 -0
  278. package/mcp.json +796 -0
  279. package/package.json +113 -0
  280. package/server.json +23 -0
  281. package/smithery.yaml +11 -0
@@ -0,0 +1,583 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Weavetab AI Voice Hub</title>
6
+ <style>
7
+ :root {
8
+ --bg: #050506;
9
+ --panel-bg: rgba(13, 13, 16, 0.7);
10
+ --border: rgba(255, 255, 255, 0.08);
11
+ --accent: #8b5cf6;
12
+ --accent-glow: rgba(139, 92, 246, 0.4);
13
+ --text: #fafafa;
14
+ --text-muted: #71717a;
15
+ --orb-idle: #3f3f46;
16
+ --orb-active: #8b5cf6;
17
+ --orb-speaking: #3b82f6;
18
+ }
19
+ * { margin: 0; padding: 0; box-sizing: border-box; }
20
+ body {
21
+ background: var(--bg);
22
+ color: var(--text);
23
+ font-family: 'Inter', system-ui, -apple-system, sans-serif;
24
+ overflow-x: hidden;
25
+ min-height: 100vh;
26
+ display: flex;
27
+ flex-direction: column;
28
+ }
29
+
30
+ .bg-glow {
31
+ position: fixed;
32
+ top: -20vh;
33
+ left: -20vw;
34
+ width: 60vw;
35
+ height: 60vh;
36
+ background: radial-gradient(circle, rgba(139, 92, 246, 0.1) 0%, rgba(0,0,0,0) 70%);
37
+ z-index: -1;
38
+ pointer-events: none;
39
+ }
40
+ .bg-glow-2 {
41
+ position: fixed;
42
+ bottom: -20vh;
43
+ right: -20vw;
44
+ width: 60vw;
45
+ height: 60vh;
46
+ background: radial-gradient(circle, rgba(56, 189, 248, 0.05) 0%, rgba(0,0,0,0) 70%);
47
+ z-index: -1;
48
+ pointer-events: none;
49
+ }
50
+
51
+ header {
52
+ padding: 20px 32px;
53
+ display: flex;
54
+ justify-content: space-between;
55
+ align-items: center;
56
+ border-bottom: 1px solid var(--border);
57
+ background: rgba(5, 5, 6, 0.8);
58
+ backdrop-filter: blur(12px);
59
+ -webkit-backdrop-filter: blur(12px);
60
+ position: sticky;
61
+ top: 0;
62
+ z-index: 100;
63
+ }
64
+ .brand {
65
+ display: flex;
66
+ align-items: center;
67
+ gap: 12px;
68
+ font-size: 1.2rem;
69
+ font-weight: 600;
70
+ letter-spacing: -0.02em;
71
+ }
72
+ .branch-badge {
73
+ background: rgba(139, 92, 246, 0.15);
74
+ border: 1px solid rgba(139, 92, 246, 0.3);
75
+ color: #c4b5fd;
76
+ padding: 4px 12px;
77
+ border-radius: 999px;
78
+ font-size: 0.75rem;
79
+ font-family: monospace;
80
+ }
81
+
82
+ main {
83
+ flex: 1;
84
+ padding: 32px;
85
+ display: flex;
86
+ flex-direction: column;
87
+ gap: 32px;
88
+ max-width: 1200px;
89
+ margin: 0 auto;
90
+ width: 100%;
91
+ }
92
+
93
+ .panel {
94
+ background: var(--panel-bg);
95
+ border: 1px solid var(--border);
96
+ border-radius: 24px;
97
+ padding: 32px;
98
+ backdrop-filter: blur(24px);
99
+ -webkit-backdrop-filter: blur(24px);
100
+ box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4);
101
+ }
102
+ .panel-title {
103
+ font-size: 0.85rem;
104
+ font-weight: 600;
105
+ color: var(--text-muted);
106
+ margin-bottom: 24px;
107
+ text-transform: uppercase;
108
+ letter-spacing: 0.1em;
109
+ display: flex;
110
+ justify-content: space-between;
111
+ align-items: center;
112
+ }
113
+
114
+ /* --- VOICE SYSTEM UI --- */
115
+ .voice-hub {
116
+ display: flex;
117
+ flex-direction: column;
118
+ align-items: center;
119
+ justify-content: center;
120
+ gap: 40px;
121
+ text-align: center;
122
+ padding: 60px 0;
123
+ }
124
+
125
+ .orb-container {
126
+ position: relative;
127
+ width: 200px;
128
+ height: 200px;
129
+ display: flex;
130
+ align-items: center;
131
+ justify-content: center;
132
+ cursor: pointer;
133
+ transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
134
+ }
135
+ .orb-container:hover { transform: scale(1.05); }
136
+ .orb-container:active { transform: scale(0.95); }
137
+
138
+ .orb {
139
+ position: absolute;
140
+ width: 100px;
141
+ height: 100px;
142
+ border-radius: 50%;
143
+ background: var(--orb-idle);
144
+ box-shadow: 0 0 20px rgba(0,0,0,0.5);
145
+ transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
146
+ z-index: 2;
147
+ }
148
+ .orb.listening {
149
+ background: var(--orb-active);
150
+ box-shadow: 0 0 40px var(--accent-glow), 0 0 80px rgba(139, 92, 246, 0.2);
151
+ transform: scale(1.2);
152
+ }
153
+ .orb.speaking {
154
+ background: var(--orb-speaking);
155
+ box-shadow: 0 0 40px rgba(59, 130, 246, 0.4), 0 0 80px rgba(59, 130, 246, 0.2);
156
+ }
157
+
158
+ .orb-ring {
159
+ position: absolute;
160
+ border: 2px solid var(--border);
161
+ border-radius: 50%;
162
+ transition: all 0.5s ease;
163
+ z-index: 1;
164
+ }
165
+ .ring-1 { width: 140px; height: 140px; animation: rotate 10s linear infinite; }
166
+ .ring-2 { width: 180px; height: 180px; animation: rotate 15s linear infinite reverse; border-style: dashed; }
167
+
168
+ @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
169
+
170
+ .voice-status {
171
+ font-size: 1.5rem;
172
+ font-weight: 500;
173
+ color: var(--text);
174
+ min-height: 1.5em;
175
+ transition: opacity 0.3s;
176
+ }
177
+ .voice-transcript {
178
+ font-size: 1rem;
179
+ color: var(--text-muted);
180
+ max-width: 600px;
181
+ min-height: 1.5em;
182
+ font-style: italic;
183
+ }
184
+
185
+ .voice-controls {
186
+ display: flex;
187
+ gap: 16px;
188
+ justify-content: center;
189
+ }
190
+ .btn-voice {
191
+ background: rgba(255, 255, 255, 0.05);
192
+ border: 1px solid var(--border);
193
+ color: var(--text);
194
+ padding: 12px 24px;
195
+ border-radius: 999px;
196
+ cursor: pointer;
197
+ font-family: inherit;
198
+ font-size: 0.9rem;
199
+ transition: all 0.2s;
200
+ }
201
+ .btn-voice:hover { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.2); }
202
+ .btn-voice.active { background: var(--accent); border-color: var(--accent); color: white; }
203
+
204
+ /* --- Permissions Grid --- */
205
+ .permissions-grid {
206
+ display: grid;
207
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
208
+ gap: 16px;
209
+ }
210
+ .perm-btn {
211
+ background: rgba(255, 255, 255, 0.03);
212
+ border: 1px solid var(--border);
213
+ color: var(--text);
214
+ padding: 16px;
215
+ border-radius: 16px;
216
+ cursor: pointer;
217
+ display: flex;
218
+ flex-direction: column;
219
+ align-items: flex-start;
220
+ gap: 8px;
221
+ transition: all 0.2s ease;
222
+ font-family: inherit;
223
+ text-align: left;
224
+ }
225
+ .perm-btn:hover { background: rgba(255, 255, 255, 0.07); transform: translateY(-2px); }
226
+ .perm-icon { font-size: 1.25rem; margin-bottom: 4px; }
227
+ .perm-label { font-weight: 500; font-size: 0.9rem; }
228
+ .perm-desc { font-size: 0.8rem; color: var(--text-muted); }
229
+
230
+ /* --- Workspace --- */
231
+ #workspace-panel { margin-top: 32px; }
232
+ #canvas-container { display: flex; flex-direction: column; align-items: center; gap: 16px; width: 100%; }
233
+ canvas { background: #000; border: 1px solid var(--border); border-radius: 16px; max-width: 100%; box-shadow: 0 10px 40px rgba(0,0,0,0.5); }
234
+ #content-area { display: none; width: 100%; background: #fff; color: #000; border-radius: 16px; min-height: 600px; padding: 24px; overflow: auto; }
235
+ </style>
236
+ </head>
237
+ <body>
238
+ <div class="bg-glow"></div>
239
+ <div class="bg-glow-2"></div>
240
+
241
+ <header>
242
+ <div class="brand">
243
+ <span style="color: var(--accent);">✦</span> Weavetab <span style="font-weight: 300; opacity: 0.6; margin-left: 4px;">VoiceHub</span>
244
+ </div>
245
+ <div class="branch-badge" id="branch-display">branch: default</div>
246
+ </header>
247
+
248
+ <main>
249
+ <!-- Voice Interface Panel -->
250
+ <div class="panel">
251
+ <div class="panel-title">AI Voice Command System</div>
252
+ <div class="voice-hub">
253
+ <div class="orb-container" id="voice-trigger">
254
+ <div class="orb-ring ring-1"></div>
255
+ <div class="orb-ring ring-2"></div>
256
+ <div class="orb" id="voice-orb"></div>
257
+ </div>
258
+
259
+ <div class="voice-status" id="status-text">Ready to listen</div>
260
+ <div class="voice-transcript" id="transcript-text">"Click the orb or press Space to speak"</div>
261
+
262
+ <div class="voice-controls">
263
+ <button class="btn-voice" id="btn-listen">Start Listening</button>
264
+ <button class="btn-voice" id="btn-voice-settings">Voice Settings</button>
265
+ </div>
266
+ </div>
267
+ </div>
268
+
269
+ <!-- Permissions Panel -->
270
+ <div class="panel">
271
+ <div class="panel-title">System Permissions</div>
272
+ <div class="permissions-grid">
273
+ <button class="perm-btn" onclick="requestMic()">
274
+ <span class="perm-icon">🎤</span>
275
+ <span class="perm-label">Microphone</span>
276
+ <span class="perm-desc">Required for Realtime Voice</span>
277
+ </button>
278
+ <button class="perm-btn" onclick="requestCamera()">
279
+ <span class="perm-icon">📷</span>
280
+ <span class="perm-label">Camera</span>
281
+ <span class="perm-desc">Grant video stream access</span>
282
+ </button>
283
+ <button class="perm-btn" onclick="requestGeolocation()">
284
+ <span class="perm-icon">📍</span>
285
+ <span class="perm-label">Location</span>
286
+ <span class="perm-desc">Allow location services</span>
287
+ </button>
288
+ <button class="perm-btn" onclick="requestNotifications()">
289
+ <span class="perm-icon">🔔</span>
290
+ <span class="perm-label">Notifications</span>
291
+ <span class="perm-desc">Allow system alerts</span>
292
+ </button>
293
+ </div>
294
+ </div>
295
+
296
+ <!-- Workspace Panel -->
297
+ <div class="panel" id="workspace-panel">
298
+ <div class="panel-title">Workspace</div>
299
+ <div id="canvas-container">
300
+ <canvas id="wt-canvas" width="800" height="600"></canvas>
301
+ </div>
302
+ <div id="content-area"></div>
303
+ </div>
304
+ </main>
305
+
306
+ <script>
307
+ // --- Infrastructure Setup ---
308
+ const urlParams = new URLSearchParams(window.location.search);
309
+ const branch = urlParams.get('branch') || 'default';
310
+ document.getElementById('branch-display').textContent = `branch: ${branch}`;
311
+
312
+ // --- Voice System Implementation ---
313
+ class WeavetabVoiceSystem {
314
+ constructor() {
315
+ this.orb = document.getElementById('voice-orb');
316
+ this.status = document.getElementById('status-text');
317
+ this.transcript = document.getElementById('transcript-text');
318
+ this.btnListen = document.getElementById('btn-listen');
319
+ this.trigger = document.getElementById('voice-trigger');
320
+
321
+ this.isListening = false;
322
+ this.isSpeaking = false;
323
+
324
+ // Speech Recognition Setup
325
+ const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
326
+ if (!SpeechRecognition) {
327
+ this.status.textContent = "Speech API not supported";
328
+ this.status.style.color = "#ef4444";
329
+ return;
330
+ }
331
+
332
+ this.recognition = new SpeechRecognition();
333
+ this.recognition.continuous = false;
334
+ this.recognition.interimResults = true;
335
+ this.recognition.lang = 'en-US';
336
+
337
+ this.initEventListeners();
338
+ this.setupRecognition();
339
+ }
340
+
341
+ initEventListeners() {
342
+ this.btnListen.onclick = () => this.toggleListening();
343
+ this.trigger.onclick = () => this.toggleListening();
344
+
345
+ window.addEventListener('keydown', (e) => {
346
+ if (e.code === 'Space' && document.activeElement.tagName !== 'INPUT') {
347
+ e.preventDefault();
348
+ this.toggleListening();
349
+ }
350
+ });
351
+ }
352
+
353
+ setupRecognition() {
354
+ this.recognition.onstart = () => {
355
+ this.isListening = true;
356
+ this.updateUI('listening');
357
+ };
358
+
359
+ this.recognition.onresult = (event) => {
360
+ const result = event.results[0][0].transcript;
361
+ this.transcript.textContent = `"${result}"`;
362
+
363
+ if (event.results[0].isFinal) {
364
+ this.handleVoiceCommand(result);
365
+ }
366
+ };
367
+
368
+ this.recognition.onerror = (e) => {
369
+ console.error("Voice Error:", e);
370
+ this.stopListening();
371
+ this.status.textContent = "Error capturing voice";
372
+ };
373
+
374
+ this.recognition.onend = () => {
375
+ if (this.isListening) this.recognition.start(); // Keep alive if we intend to listen
376
+ else this.stopListening();
377
+ };
378
+ }
379
+
380
+ toggleListening() {
381
+ if (this.isListening) this.stopListening();
382
+ else this.startListening();
383
+ }
384
+
385
+ startListening() {
386
+ try {
387
+ this.recognition.start();
388
+ this.btnListen.classList.add('active');
389
+ } catch (e) {
390
+ console.error("Start Error:", e);
391
+ }
392
+ }
393
+
394
+ stopListening() {
395
+ this.isListening = false;
396
+ this.recognition.stop();
397
+ this.btnListen.classList.remove('active');
398
+ this.updateUI('idle');
399
+ }
400
+
401
+ updateUI(state) {
402
+ this.orb.className = 'orb';
403
+ if (state === 'listening') {
404
+ this.orb.classList.add('listening');
405
+ this.status.textContent = "I'm listening...";
406
+ } else if (state === 'speaking') {
407
+ this.orb.classList.add('speaking');
408
+ this.status.textContent = "Weavetab is speaking";
409
+ } else {
410
+ this.status.textContent = "Ready to listen";
411
+ }
412
+ }
413
+
414
+ async handleVoiceCommand(text) {
415
+ this.stopListening();
416
+ this.status.textContent = "Processing...";
417
+
418
+ // Simulate AI Thought
419
+ setTimeout(() => {
420
+ const response = this.generateAIResponse(text);
421
+ this.speak(response);
422
+ }, 600);
423
+ }
424
+
425
+ generateAIResponse(text) {
426
+ const t = text.toLowerCase();
427
+ if (t.includes('hello') || t.includes('hi')) return "Hello. I am the Weavetab Voice System. How can I assist your workflow today?";
428
+ if (t.includes('time')) return `The current system time is ${new Date().toLocaleTimeString()}.`;
429
+ if (t.includes('who are you')) return "I am your enterprise AI agent, integrated directly into the Weavetab core for real-time browser orchestration.";
430
+ if (t.includes('status')) return "All systems are operational. CDP bridge is active and session is stable.";
431
+
432
+ return `You said: ${text}. I am processing this request through the Weavetab neural bridge.`;
433
+ }
434
+
435
+ speak(text) {
436
+ this.isSpeaking = true;
437
+ this.updateUI('speaking');
438
+
439
+ const utterance = new SpeechSynthesisUtterance(text);
440
+
441
+ // Attempt to find a premium "Enterprise" voice
442
+ const voices = window.speechSynthesis.getVoices();
443
+ const premiumVoice = voices.find(v => v.name.includes('Google US English') || v.name.includes('Samantha') || v.name.includes('Microsoft Aria'));
444
+ if (premiumVoice) utterance.voice = premiumVoice;
445
+
446
+ utterance.pitch = 0.9; // Slightly deeper for "Enterprise" feel
447
+ utterance.rate = 1.0;
448
+
449
+ utterance.onend = () => {
450
+ this.isSpeaking = false;
451
+ this.updateUI('idle');
452
+ };
453
+
454
+ window.speechSynthesis.speak(utterance);
455
+ }
456
+ }
457
+
458
+ // Initialize Voice System
459
+ const voiceSystem = new WeavetabVoiceSystem();
460
+
461
+ // --- Go Home Function ---
462
+ const browserAPI = typeof browser !== 'undefined' ? browser : chrome;
463
+ function goHome() {
464
+ // Reset to default branch and clear any error state
465
+ const url = new URL(window.location.href);
466
+ url.searchParams.set('branch', 'default');
467
+ window.location.href = url.toString();
468
+ }
469
+
470
+ // --- Original Dashboard Logic ---
471
+ async function requestMic() {
472
+ try {
473
+ await navigator.mediaDevices.getUserMedia({ audio: true });
474
+ alert('Microphone permission granted!');
475
+ } catch (e) {
476
+ alert('Microphone permission failed: ' + e.message);
477
+ }
478
+ }
479
+ async function requestCamera() {
480
+ try {
481
+ const stream = await navigator.mediaDevices.getUserMedia({ video: true });
482
+ stream.getTracks().forEach(t => t.stop());
483
+ alert('Camera granted!');
484
+ } catch (e) { alert('Camera failed: ' + e.message); }
485
+ }
486
+ function requestGeolocation() {
487
+ navigator.geolocation.getCurrentPosition(() => alert('Location granted!'), (e) => alert(e.message));
488
+ }
489
+ async function requestNotifications() {
490
+ const p = await Notification.requestPermission();
491
+ alert('Notification: ' + p);
492
+ }
493
+
494
+ const canvas = document.getElementById('wt-canvas');
495
+ const ctx = canvas.getContext('2d');
496
+ const contentArea = document.getElementById('content-area');
497
+ const container = document.getElementById('canvas-container');
498
+
499
+ function drawPlaceholder() {
500
+ ctx.fillStyle = '#000';
501
+ ctx.fillRect(0, 0, 800, 600);
502
+ ctx.fillStyle = '#8b5cf6';
503
+ ctx.font = 'bold 36px system-ui, sans-serif';
504
+ ctx.textAlign = 'center';
505
+ ctx.fillText('Agent Canvas', 400, 260);
506
+ ctx.fillStyle = '#a1a1aa';
507
+ ctx.font = '18px system-ui, sans-serif';
508
+ ctx.fillText('Real-time Voice Active', 400, 310);
509
+ }
510
+
511
+ // Add error handling for browserAPI.storage access
512
+ if (typeof chrome === 'undefined' || !browserAPI.storage || !browserAPI.storage.local) {
513
+ console.error('Chrome storage API not available');
514
+ document.body.innerHTML = `
515
+ <div style="display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;background:#050506;color:#fff;font-family:sans-serif;">
516
+ <h2 style="color:#ef4444;margin-bottom:20px;">Extension Not Loaded</h2>
517
+ <p style="margin-bottom:20px;">The WeaveTab extension is not properly loaded.</p>
518
+ <div style="display:flex;gap:10px;">
519
+ <button onclick="location.reload()" style="padding:12px 24px;background:#8b5cf6;color:#fff;border:none;border-radius:8px;cursor:pointer;">Retry</button>
520
+ <button onclick="goHome()" style="padding:12px 24px;background:#3b82f6;color:#fff;border:none;border-radius:8px;cursor:pointer;">Go Home</button>
521
+ </div>
522
+ </div>
523
+ `;
524
+ drawPlaceholder();
525
+ } else {
526
+ browserAPI.storage.local.get([`branch_${branch}_html`, `branch_${branch}_canvas`], (result) => {
527
+ if (browserAPI.runtime.lastError) {
528
+ console.error('Chrome storage error:', browserAPI.runtime.lastError);
529
+ document.body.innerHTML = `
530
+ <div style="display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;background:#050506;color:#fff;font-family:sans-serif;">
531
+ <h2 style="color:#ef4444;margin-bottom:20px;">Storage Error</h2>
532
+ <p style="margin-bottom:20px;">${browserAPI.runtime.lastError.message}</p>
533
+ <div style="display:flex;gap:10px;">
534
+ <button onclick="location.reload()" style="padding:12px 24px;background:#8b5cf6;color:#fff;border:none;border-radius:8px;cursor:pointer;">Retry</button>
535
+ <button onclick="goHome()" style="padding:12px 24px;background:#3b82f6;color:#fff;border:none;border-radius:8px;cursor:pointer;">Go Home</button>
536
+ </div>
537
+ </div>
538
+ `;
539
+ } else {
540
+ if (result[`branch_${branch}_html`]) {
541
+ contentArea.textContent = result[`branch_${branch}_html`];
542
+ container.style.display = 'none';
543
+ contentArea.style.display = 'block';
544
+ } else {
545
+ drawPlaceholder();
546
+ }
547
+ }
548
+ });
549
+ }
550
+
551
+ // Add error handling for storage save interval
552
+ function safeStorageSave() {
553
+ if (typeof chrome === 'undefined' || !browserAPI.storage || !browserAPI.storage.local) {
554
+ return;
555
+ }
556
+ try {
557
+ if (contentArea.style.display === 'block') {
558
+ browserAPI.storage.local.set({ [`branch_${branch}_html`]: contentArea.innerHTML }).catch(e => {
559
+ console.error('Storage save error:', e);
560
+ });
561
+ } else {
562
+ browserAPI.storage.local.set({ [`branch_${branch}_canvas`]: canvas.toDataURL() }).catch(e => {
563
+ console.error('Storage save error:', e);
564
+ });
565
+ }
566
+ } catch (e) {
567
+ console.error('Storage save error:', e);
568
+ }
569
+ }
570
+
571
+ setInterval(safeStorageSave, 1000);
572
+
573
+ window.addEventListener('wt-dashboard-command', (e) => {
574
+ const { command, params } = e.detail || {};
575
+ if (command === 'show-canvas') { container.style.display = 'flex'; contentArea.style.display = 'none'; }
576
+ if (command === 'show-html') {
577
+ container.style.display = 'none'; contentArea.style.display = 'block';
578
+ if (params?.html) contentArea.innerHTML = params.html;
579
+ }
580
+ });
581
+ </script>
582
+ </body>
583
+ </html>
@@ -0,0 +1,73 @@
1
+ "use strict";(()=>{var S={};window.wtState=S;window.addEventListener("message",e=>{let{type:t,...i}=e.data;if(t?.startsWith("RT_")){S[t]=i;return}$(t,i)});function $(e,t){e==="REHYDRATE"&&window.dispatchEvent(new CustomEvent("wt-rehydrate",{detail:t}))}var c=document.getElementById("rt-canvas"),s=c.getContext("2d"),d=window.innerWidth/2,u=window.innerHeight/2,D=d,L=u,v=0,_=0,g="idle",T="",A=!1,E=!0,Y=!1;window.addEventListener("message",function(e){e.data&&(e.data.type==="WT_SIDEPANEL_STATE"&&(A=!!e.data.open,A&&(T="")),e.data.type==="WT_SUPPRESS_THOUGHT_HUD"&&(Y=!0,T=""),e.data.type==="WT_SCRIPTED_PILL_TOGGLE"&&(E=!!e.data.enabled))});var W=[],y=[],N=0,h=0;function F(){c.width=window.innerWidth,c.height=window.innerHeight}window.addEventListener("resize",F);F();var H=.15,P=.6,K=0,x=0,C=0;var U=0,I=0;function M(){let e=window.wtState||{};e.RT_CURSOR_MOVE&&(d=e.RT_CURSOR_MOVE.x,u=e.RT_CURSOR_MOVE.y,g=e.RT_CURSOR_MOVE.phase||"idle",delete e.RT_CURSOR_MOVE),e.RT_CLICK&&(X(e.RT_CLICK.x,e.RT_CLICK.y,"#3b82f6"),g="clicking",C=Date.now(),setTimeout(()=>{g==="clicking"&&(g="idle")},300),delete e.RT_CLICK),e.RT_SCROLL&&(N=e.RT_SCROLL.y,h=e.RT_SCROLL.ratio,delete e.RT_SCROLL);let t=W.length>0||y.length>0||T||g!=="idle"||Math.abs(d-U)>.5||Math.abs(u-I)>.5;if(U=d,I=u,!t){h>0&&h<1&&(s.clearRect(0,0,c.width,c.height),O()),requestAnimationFrame(M);return}s.clearRect(0,0,c.width,c.height),v+=(d-D)*H,_+=(u-L)*H,v*=P,_*=P;let i=Date.now();if(T&&g!=="typing"&&g!=="clicking"){K+=.016,x+=.03;let n=3;d+=Math.sin(x)*n,u+=Math.cos(x*.7)*n,Math.random()<.02&&(x+=.5)}if(g==="clicking"&&i-C<300){let r=(Math.random()-.5)*2.5,w=(Math.random()-.5)*2.5;d+=r,u+=w;let l=(i-C)/50;d+=Math.sin(l)*1,u+=Math.cos(l)*1}D+=v,L+=_,E&&J(),E&&O(),requestAnimationFrame(M)}function X(e,t,i){for(let n=0;n<15;n++){let r=Math.random()*Math.PI*2,w=Math.random()*4+1;W.push({x:e,y:t,vx:Math.cos(r)*w,vy:Math.sin(r)*w,life:1,color:i})}for(let n=0;n<3;n++)setTimeout(()=>{y.push({x:e,y:t,radius:0,alpha:1})},n*100)}function J(){for(let e=y.length-1;e>=0;e--){let t=y[e];if(t.radius+=3,t.alpha-=.015,t.alpha<=0){y.splice(e,1);continue}s.beginPath(),s.arc(t.x,t.y,t.radius,0,Math.PI*2),s.strokeStyle=`rgba(59, 130, 246, ${t.alpha})`,s.lineWidth=3,s.shadowColor="#3b82f6",s.shadowBlur=10,s.stroke()}}function O(){if(h<=0||h>=1)return;let e=4,t=60,i=c.width-e-10,n=10+(c.height-t-20)*h;s.fillStyle="rgba(59, 130, 246, 0.5)",s.beginPath(),s.roundRect(i,n,e,t,2),s.fill()}requestAnimationFrame(M);var p=!0;function B(){window.addEventListener("message",e=>{e.data.type==="TOGGLE_HUD"&&z()}),window.toggleHUD=z}function z(){p=!p;let e=document.getElementById("rt-canvas"),t=document.getElementById("widgets");e&&(e.style.display=p?"block":"none"),t&&(t.style.display=p?"block":"none"),window.parent.postMessage({type:"HUD_STATE_CHANGED",state:{hudVisible:p}},"*")}function G(e){p=e;let t=document.getElementById("rt-canvas"),i=document.getElementById("widgets");t&&(t.style.display=p?"block":"none"),i&&(i.style.display=p?"block":"none")}var b=!1,a=null,o=null,Q="console";function q(){console.log("[Weavetab HUD] Debug menu initialized"),window.addEventListener("message",e=>{console.log("[Weavetab HUD] Received message:",e.data.type),e.data.type==="TOGGLE_DEBUG"&&(console.log("[Weavetab HUD] Toggling debug menu"),V())}),window.toggleDebugMenu=V,console.log("[Weavetab HUD] Debug menu ready - use Ctrl+F3 or WeaveTabHUD.toggleDebugMenu()")}function V(){console.log("[Weavetab HUD] toggleDebugMenu called, current state:",b),b=!b,a||(console.log("[Weavetab HUD] Creating debug menu container"),Z()),a&&(a.style.display=b?"flex":"none",console.log("[Weavetab HUD] Debug menu visibility set to:",b)),window.parent.postMessage({type:"HUD_STATE_CHANGED",state:{debugMenuVisible:b}},"*")}function Z(){a=document.createElement("div"),a.id="wt-debug-menu",a.style.cssText=`
2
+ position: fixed;
3
+ top: 50%;
4
+ left: 50%;
5
+ transform: translate(-50%, -50%);
6
+ width: 700px;
7
+ max-height: 80vh;
8
+ background: rgba(17, 17, 19, 0.98);
9
+ border: 1px solid #3b82f6;
10
+ border-radius: 8px;
11
+ pointer-events: auto;
12
+ z-index: 1000;
13
+ display: none;
14
+ flex-direction: column;
15
+ font-family: 'IBM Plex Mono', monospace;
16
+ font-size: 12px;
17
+ color: #e8e8f0;
18
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
19
+ `;let e=document.createElement("div");e.style.cssText=`
20
+ padding: 12px 16px;
21
+ border-bottom: 1px solid #2a2a30;
22
+ display: flex;
23
+ justify-content: space-between;
24
+ align-items: center;
25
+ background: rgba(59, 130, 246, 0.1);
26
+ `,e.innerHTML=`
27
+ <span style="color: #60a5fa; font-weight: 600;">\u{1F527} WeaveTab Debug Menu</span>
28
+ <span style="color: #6b7280; font-size: 10px;">Ctrl+F3 to toggle</span>
29
+ `,a.appendChild(e);let t=document.createElement("div");t.style.cssText=`
30
+ display: flex;
31
+ border-bottom: 1px solid #2a2a30;
32
+ padding: 8px 16px;
33
+ gap: 4px;
34
+ `,["Console","State","Actions","Network"].forEach((l,f)=>{let m=document.createElement("button");m.textContent=l,m.dataset.tab=l.toLowerCase(),m.style.cssText=`
35
+ padding: 6px 12px;
36
+ background: ${f===0?"#3b82f6":"transparent"};
37
+ border: none;
38
+ color: ${f===0?"#fff":"#9ca3af"};
39
+ border-radius: 4px;
40
+ cursor: pointer;
41
+ font-size: 11px;
42
+ font-family: inherit;
43
+ `,m.onclick=()=>ee(l.toLowerCase()),t.appendChild(m)}),a.appendChild(t);let n=document.createElement("div");n.id="wt-debug-content",n.style.cssText=`
44
+ flex: 1;
45
+ overflow-y: auto;
46
+ padding: 12px 16px;
47
+ min-height: 300px;
48
+ `,o=document.createElement("div"),o.id="wt-debug-console",o.style.cssText=`
49
+ font-family: 'IBM Plex Mono', monospace;
50
+ font-size: 11px;
51
+ line-height: 1.4;
52
+ `,o.innerHTML=`
53
+ <div style="color: #6b7280;">[Debug Console Ready]</div>
54
+ <div style="color: #6b7280;">Press Ctrl+F3 to close this menu</div>
55
+ <div style="color: #6b7280; margin-top: 8px;">Use browserAsk to test messaging system</div>
56
+ `,n.appendChild(o),a.appendChild(n);let r=document.createElement("div");r.style.cssText=`
57
+ padding: 8px 16px;
58
+ border-top: 1px solid #2a2a30;
59
+ display: flex;
60
+ gap: 8px;
61
+ `,[{label:"Clear",color:"#6b7280",action:()=>te()},{label:"Test Ask",color:"#3b82f6",action:()=>ne()},{label:"Export",color:"#22c55e",action:()=>ie()}].forEach(l=>{let f=document.createElement("button");f.textContent=l.label,f.style.cssText=`
62
+ padding: 4px 12px;
63
+ background: transparent;
64
+ border: 1px solid ${l.color};
65
+ color: ${l.color};
66
+ border-radius: 4px;
67
+ cursor: pointer;
68
+ font-size: 10px;
69
+ font-family: inherit;
70
+ `,f.onclick=l.action,r.appendChild(f)}),a.appendChild(r),document.getElementById("widgets").appendChild(a)}function ee(e){Q=e,a?.querySelectorAll("button[dataset-tab]")?.forEach(i=>{let n=i.dataset.tab===e;i.style.background=n?"#3b82f6":"transparent",i.style.color=n?"#fff":"#9ca3af"}),o&&(e==="console"?o.style.display="block":(o.style.display="none",o.innerHTML=`<div style="color: #6b7280;">[${e.charAt(0).toUpperCase()+e.slice(1)} Tab - Coming Soon]</div>`))}function te(){o&&(o.innerHTML='<div style="color: #6b7280;">[Console Cleared]</div>')}function ne(){R("Testing ask system...","info"),window.parent.postMessage({type:"TEST_ASK_SYSTEM"},"*")}function ie(){if(R("Exporting logs...","info"),o){let e=o.innerText,t=new Blob([e],{type:"text/plain"}),i=URL.createObjectURL(t),n=document.createElement("a");n.href=i,n.download="weavetab-debug-logs.txt",n.click(),URL.revokeObjectURL(i),R("Logs exported successfully","info")}}function R(e,t="info"){if(!o)return;let i={info:"#60a5fa",warn:"#f59e0b",error:"#ef4444"},n=new Date().toLocaleTimeString(),r=document.createElement("div");r.style.cssText=`
71
+ margin-bottom: 4px;
72
+ color: ${i[t]};
73
+ `,r.innerHTML=`<span style="color: #6b7280;">[${n}]</span> ${e}`,o.appendChild(r),o.scrollTop=o.scrollHeight}function j(e){b=e,a&&(a.style.display=b?"flex":"none")}var oe=!1;function k(){try{oe=window.parent.__wt_devMode===!0}catch(e){console.log("[Weavetab HUD] Could not check devMode:",e)}}B();q();k();window.addEventListener("message",e=>{e.data.type==="WT_CONFIG_UPDATE"&&k()});window.addEventListener("message",e=>{if(e.data.type==="REHYDRATE"){let t=e.data.state||{};t.hudVisible!==void 0&&G(t.hudVisible),t.debugMenuVisible!==void 0&&j(t.debugMenuVisible),k(),window.dispatchEvent(new CustomEvent("wt-rehydrate",{detail:t}))}});window.WeaveTabHUD={};})();
@@ -0,0 +1,20 @@
1
+ <!DOCTYPE html>
2
+ <html style="background: transparent">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>WeaveTab HUD</title>
6
+ <style>
7
+ body {
8
+ margin: 0;
9
+ background: transparent;
10
+ overflow: hidden;
11
+ font-family: 'IBM Plex Mono', 'Consolas', 'Menlo', 'Courier New', monospace;
12
+ }
13
+ </style>
14
+ </head>
15
+ <body style="margin:0;background:transparent;overflow:hidden">
16
+ <canvas id="rt-canvas" style="position:fixed;inset:0;pointer-events:none;z-index:0"></canvas>
17
+ <div id="widgets" style="position:fixed;inset:0;pointer-events:none;z-index:1"></div>
18
+ <script src="hud.js"></script>
19
+ </body>
20
+ </html>