lobsterboard 0.1.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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,95 @@
1
+ # LobsterBoard Changelog
2
+
3
+ All notable changes to LobsterBoard will be documented in this file.
4
+
5
+ ---
6
+
7
+ ## [Unreleased]
8
+
9
+ ### Fixed
10
+ - Text-header widget "Show Border" checkbox now works — toggling it off removes the card background, border, and box-shadow from the `.placed-widget` container
11
+ - Fix text-header, horizontal-line, and vertical-line widgets disappearing after save/reload — unknown widget types (e.g. removed `topbar`) crashed `renderWidget`, stopping all subsequent widgets from loading
12
+ - Add guard in `renderWidget` to skip unknown widget types gracefully
13
+ - Wrap each widget render in try/catch so one bad widget can't prevent others from loading
14
+
15
+ ---
16
+
17
+ ## [0.1.0] - 2026-02-05
18
+
19
+ ### 🎉 Initial Release
20
+
21
+ The first public version of LobsterBoard - a visual dashboard builder for the OpenClaw community.
22
+
23
+ ### Added
24
+
25
+ #### Core Builder
26
+ - Drag-and-drop widget placement on canvas
27
+ - Grid snapping (20px) for precise alignment
28
+ - Widget resize handles
29
+ - Properties panel for configuring widgets
30
+ - Live preview modal with inlined styles
31
+ - Export to ZIP (standalone HTML/CSS/JS)
32
+
33
+ #### Canvas Features
34
+ - 15+ screen size presets (1080p, 4K, tablets, ultrawide, portrait)
35
+ - Custom dimension support
36
+ - Zoom controls (+/-, Fit, 1:1)
37
+ - Keyboard shortcuts (Ctrl +/-, Ctrl+scroll)
38
+
39
+ #### Widgets (40+)
40
+ - **AI/LLM:** Claude Usage, GPT Usage, Gemini Usage, AI Usage (All), Cost Tracker, API Status, Active Sessions, Token Gauge
41
+ - **Basics:** Local Weather, World Weather, Clock, World Clock, Countdown, Stat Card, Battery Status
42
+ - **System:** CPU/Memory, Disk Usage, Network Speed, Docker, Uptime Monitor
43
+ - **OpenClaw:** Auth Status, Sleep Ring, Release, Activity List, Cron Jobs, System Log
44
+ - **Productivity:** Todo List, Calendar, Email Count, Pomodoro, Notes, GitHub Stats
45
+ - **Finance:** Stock Ticker, Crypto Price
46
+ - **Smart Home:** Indoor Climate, Camera Feed, Power Usage
47
+ - **Entertainment:** Now Playing, Quote of Day
48
+ - **Content:** Quick Links, RSS Feed, Image Embed, Iframe Embed
49
+ - **Bars:** Top Nav Bar, News Ticker, RSS Ticker
50
+
51
+ #### Branding
52
+ - LobsterBoard name and mascot 🦞
53
+ - Logo wordmark for header
54
+ - Mascot illustration for sidebar
55
+ - Favicon and Apple touch icon
56
+
57
+ #### Design
58
+ - Dark theme matching OpenClaw aesthetic
59
+ - Consistent `dash-card` styling across all widgets
60
+ - Widget headers with icons
61
+ - Sample data display (no loading spinners in builder)
62
+
63
+ ### Technical Notes
64
+ - Weather widgets use wttr.in (free, no API key required)
65
+ - API keys stored as placeholders for users to fill in post-export
66
+ - AI usage widgets require backend proxy due to CORS
67
+
68
+ ---
69
+
70
+ ## [0.1.1] - 2026-02-06
71
+
72
+ ### Changed
73
+ - Moved mascot from left sidebar to right (properties panel)
74
+ - Mascot now pinned to bottom of panel (doesn't float up)
75
+
76
+ ### Fixed
77
+ - Mascot positioning with `margin-top: auto` in flexbox
78
+
79
+ ---
80
+
81
+ ## Upcoming
82
+
83
+ ### Planned Features
84
+ - GitHub Pages deployment
85
+ - Import/export dashboard layouts (JSON)
86
+ - Widget templates and presets
87
+ - More customization options
88
+ - Community widget contributions
89
+
90
+ ---
91
+
92
+ ## Links
93
+
94
+ - **GitHub:** https://github.com/curbob/LobsterBoard
95
+ - **Issues:** https://github.com/curbob/LobsterBoard/issues
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 curbob
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # 🦞 LobsterBoard
2
+
3
+ A drag-and-drop dashboard builder for creating beautiful, customizable status boards.
4
+
5
+ ![LobsterBoard](lobsterboard-logo-final.png)
6
+
7
+ ## Features
8
+
9
+ - **Visual Builder**: Drag and drop widgets onto a grid
10
+ - **47+ Widgets**: Weather, clocks, system stats, AI usage, and more
11
+ - **Dark Theme**: Easy on the eyes, perfect for always-on displays
12
+ - **Export to HTML**: Single-file dashboards that run anywhere
13
+ - **No Backend Required**: Many widgets work with just a browser
14
+
15
+ ## Quick Start
16
+
17
+ 1. Open `index.html` in your browser
18
+ 2. Drag widgets from the sidebar onto the canvas
19
+ 3. Click widgets to edit their properties
20
+ 4. Click **Export Dashboard** to download your dashboard
21
+
22
+ ## Widget Categories
23
+
24
+ ### ✅ Works Out of Box (No API Needed)
25
+ These widgets work immediately with no configuration:
26
+ - Weather (wttr.in)
27
+ - Clock, World Clock
28
+ - Countdown, Pomodoro Timer
29
+ - Images (local, web, random rotation)
30
+ - Quick Links
31
+ - Iframe Embed
32
+ - Release Tracker (GitHub public API)
33
+
34
+ ### 🦞 OpenClaw Widgets
35
+ These widgets connect to a running [OpenClaw](https://github.com/openclaw/openclaw) gateway:
36
+ - Auth Status
37
+ - OpenClaw Release
38
+ - Activity List
39
+ - Cron Jobs
40
+ - System Log
41
+ - Session Count
42
+ - Token Gauge
43
+
44
+ **See [Using OpenClaw Widgets](#using-openclaw-widgets) below.**
45
+
46
+ ### 🔑 API Key Required
47
+ These widgets need you to provide an API key:
48
+ - News Ticker (NewsAPI)
49
+ - Stock Ticker (Finnhub)
50
+ - GitHub Stats (optional, for higher rate limits)
51
+
52
+ ### ⚠️ Custom Backend Required
53
+ These widgets need custom API endpoints:
54
+ - AI Usage (Claude, GPT, Gemini)
55
+ - CPU/Memory, Disk Usage
56
+ - Docker Containers
57
+ - And more...
58
+
59
+ ---
60
+
61
+ ## Using OpenClaw Widgets
62
+
63
+ OpenClaw widgets fetch data from your local OpenClaw gateway. Due to browser CORS restrictions, you need to either:
64
+
65
+ ### Option A: Use the Included Server (Recommended)
66
+
67
+ The server proxies API requests to OpenClaw, solving CORS issues.
68
+
69
+ 1. **Export your dashboard** from the builder (Download button)
70
+
71
+ 2. **Extract the ZIP** to a folder
72
+
73
+ 3. **`server.js` is included** in the exported ZIP
74
+
75
+ 4. **Run the server**:
76
+ ```bash
77
+ cd your-dashboard-folder
78
+ node server.js
79
+ ```
80
+
81
+ 5. **Open** http://localhost:8080 in your browser
82
+
83
+ **Configuration** (environment variables):
84
+ ```bash
85
+ # Custom port for the dashboard server
86
+ PORT=3000 node server.js
87
+
88
+ # Custom OpenClaw gateway URL (if not on default port 18789)
89
+ OPENCLAW_URL=http://localhost:YOUR_PORT node server.js
90
+
91
+ # Expose to network (⚠️ only on trusted networks!)
92
+ HOST=0.0.0.0 node server.js
93
+ ```
94
+
95
+ > **⚠️ Non-Default Gateway Port?**
96
+ >
97
+ > If your OpenClaw gateway runs on a port other than `18789` (the default), you **must** set the `OPENCLAW_URL` environment variable. Check your gateway port:
98
+ > ```bash
99
+ > grep '"port"' ~/.openclaw/openclaw.json
100
+ > ```
101
+ > Then start the server with:
102
+ > ```bash
103
+ > OPENCLAW_URL=http://localhost:YOUR_PORT node server.js
104
+ > ```
105
+
106
+ ### Option B: Run OpenClaw with CORS Headers
107
+
108
+ If you control your OpenClaw config, you can add CORS headers directly.
109
+
110
+ ---
111
+
112
+ ## Exporting Dashboards
113
+
114
+ 1. Click the **💾 Export** button in the toolbar
115
+ 2. Choose **Download Dashboard**
116
+ 3. A ZIP file is created containing:
117
+ - `index.html` - Your complete dashboard
118
+ - `server.js` - Server for OpenClaw widgets (optional)
119
+ - Any embedded images
120
+
121
+ The exported HTML is self-contained and can be:
122
+ - Opened directly in a browser (for non-API widgets)
123
+ - Served via the included Node.js server
124
+ - Hosted on any static web server
125
+
126
+ ---
127
+
128
+ ## Development
129
+
130
+ ### File Structure
131
+ ```
132
+ dashboard-builder/
133
+ ├── index.html # Main builder UI
134
+ ├── css/
135
+ │ └── styles.css # Dashboard styles
136
+ ├── js/
137
+ │ ├── builder.js # Builder logic
138
+ │ └── widgets.js # Widget definitions
139
+ ├── server.js # Node.js server for exports
140
+ └── WIDGETS-STATUS.md # Widget verification status
141
+ ```
142
+
143
+ ### Adding New Widgets
144
+
145
+ See `js/widgets.js` for widget definitions. Each widget has:
146
+ - `name`, `icon`, `category`
147
+ - `description` - Shows in properties panel
148
+ - `defaultWidth`, `defaultHeight`
149
+ - `properties` - Configurable options
150
+ - `generateHtml()` - Returns widget HTML
151
+ - `generateJs()` - Returns widget JavaScript
152
+
153
+ ---
154
+
155
+ ## License
156
+
157
+ MIT
158
+
159
+ ---
160
+
161
+ Made with 🦞 by the LobsterBoard team
@@ -0,0 +1,347 @@
1
+ /* LobsterBoard v0.1.0 - Dashboard Styles */
2
+ /* LobsterBoard Dashboard - Generated Styles */
3
+
4
+ :root {
5
+ --bg-primary: #0d1117;
6
+ --bg-secondary: #161b22;
7
+ --bg-tertiary: #21262d;
8
+ --bg-hover: #30363d;
9
+ --border: #30363d;
10
+ --text-primary: #e6edf3;
11
+ --text-secondary: #8b949e;
12
+ --text-muted: #6e7681;
13
+ --accent-blue: #58a6ff;
14
+ --accent-green: #3fb950;
15
+ --accent-orange: #d29922;
16
+ --accent-red: #f85149;
17
+ --accent-purple: #a371f7;
18
+ }
19
+
20
+ * {
21
+ box-sizing: border-box;
22
+ margin: 0;
23
+ padding: 0;
24
+ }
25
+
26
+ body {
27
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
28
+ background: var(--bg-primary);
29
+ color: var(--text-primary);
30
+ min-height: 100vh;
31
+ }
32
+
33
+ .dashboard {
34
+ margin: 0 auto;
35
+ overflow: hidden;
36
+ }
37
+
38
+ .widget-container {
39
+ overflow: hidden;
40
+ }
41
+
42
+ /* KPI Cards */
43
+ .kpi-card {
44
+ background: var(--bg-secondary);
45
+ border: 1px solid var(--border);
46
+ border-radius: 8px;
47
+ padding: 16px;
48
+ display: flex;
49
+ align-items: center;
50
+ gap: 12px;
51
+ height: 100%;
52
+ }
53
+
54
+ .kpi-sm {
55
+ padding: 12px;
56
+ }
57
+
58
+ .kpi-icon {
59
+ font-size: 24px;
60
+ }
61
+
62
+ .kpi-data {
63
+ flex: 1;
64
+ }
65
+
66
+ .kpi-value {
67
+ font-size: 20px;
68
+ font-weight: 600;
69
+ }
70
+
71
+ .kpi-value.blue { color: var(--accent-blue); }
72
+ .kpi-value.green { color: var(--accent-green); }
73
+ .kpi-value.orange { color: var(--accent-orange); }
74
+ .kpi-value.red { color: var(--accent-red); }
75
+
76
+ .kpi-label {
77
+ font-size: 12px;
78
+ color: var(--text-secondary);
79
+ margin-top: 2px;
80
+ }
81
+
82
+ .kpi-indicator {
83
+ width: 10px;
84
+ height: 10px;
85
+ border-radius: 50%;
86
+ background: var(--text-muted);
87
+ }
88
+
89
+ .kpi-indicator.green { background: var(--accent-green); }
90
+ .kpi-indicator.yellow { background: var(--accent-orange); }
91
+ .kpi-indicator.red { background: var(--accent-red); }
92
+
93
+ /* Dash Cards */
94
+ .dash-card {
95
+ background: var(--bg-secondary);
96
+ border: 1px solid var(--border);
97
+ border-radius: 8px;
98
+ display: flex;
99
+ flex-direction: column;
100
+ height: 100%;
101
+ overflow: hidden;
102
+ }
103
+
104
+ .dash-card-head {
105
+ display: flex;
106
+ justify-content: space-between;
107
+ align-items: center;
108
+ padding: 12px 16px;
109
+ border-bottom: 1px solid var(--border);
110
+ background: var(--bg-tertiary);
111
+ }
112
+
113
+ .dash-card-title {
114
+ font-size: 13px;
115
+ font-weight: 600;
116
+ }
117
+
118
+ .dash-card-badge {
119
+ font-size: 11px;
120
+ color: var(--text-secondary);
121
+ background: var(--bg-primary);
122
+ padding: 2px 8px;
123
+ border-radius: 10px;
124
+ }
125
+
126
+ .dash-card-body {
127
+ flex: 1;
128
+ padding: 12px 16px;
129
+ overflow-y: auto;
130
+ }
131
+
132
+ .compact-list {
133
+ font-size: 12px;
134
+ }
135
+
136
+ .syslog-scroll {
137
+ font-family: 'SF Mono', Monaco, monospace;
138
+ font-size: 11px;
139
+ }
140
+
141
+ /* Top Bar */
142
+ .topbar {
143
+ display: flex;
144
+ justify-content: space-between;
145
+ align-items: center;
146
+ padding: 8px 20px;
147
+ background: var(--bg-secondary);
148
+ border-bottom: 1px solid var(--border);
149
+ height: 100%;
150
+ }
151
+
152
+ .topbar-left {
153
+ display: flex;
154
+ align-items: center;
155
+ gap: 20px;
156
+ }
157
+
158
+ .topbar-brand {
159
+ font-weight: 600;
160
+ font-size: 14px;
161
+ }
162
+
163
+ .topbar-link {
164
+ color: var(--text-secondary);
165
+ text-decoration: none;
166
+ font-size: 13px;
167
+ }
168
+
169
+ .topbar-link:hover,
170
+ .topbar-link.active {
171
+ color: var(--accent-blue);
172
+ }
173
+
174
+ .topbar-right {
175
+ display: flex;
176
+ align-items: center;
177
+ gap: 12px;
178
+ }
179
+
180
+ .topbar-meta {
181
+ font-size: 12px;
182
+ color: var(--text-muted);
183
+ }
184
+
185
+ .topbar-refresh {
186
+ background: var(--bg-tertiary);
187
+ border: 1px solid var(--border);
188
+ color: var(--text-secondary);
189
+ padding: 4px 8px;
190
+ border-radius: 4px;
191
+ cursor: pointer;
192
+ }
193
+
194
+ /* List Items */
195
+ .list-item {
196
+ padding: 6px 0;
197
+ border-bottom: 1px solid var(--border);
198
+ }
199
+
200
+ .list-item:last-child {
201
+ border-bottom: none;
202
+ }
203
+
204
+ .cron-item {
205
+ display: flex;
206
+ justify-content: space-between;
207
+ padding: 6px 0;
208
+ border-bottom: 1px solid var(--border);
209
+ }
210
+
211
+ .cron-name {
212
+ color: var(--text-primary);
213
+ }
214
+
215
+ .cron-next {
216
+ color: var(--text-muted);
217
+ font-size: 11px;
218
+ }
219
+
220
+ .log-line {
221
+ padding: 2px 0;
222
+ border-bottom: 1px solid rgba(48, 54, 61, 0.5);
223
+ }
224
+
225
+ /* Weather */
226
+ .weather-row {
227
+ display: flex;
228
+ align-items: center;
229
+ gap: 10px;
230
+ padding: 8px 0;
231
+ border-bottom: 1px solid var(--border);
232
+ }
233
+
234
+ .weather-row:last-child {
235
+ border-bottom: none;
236
+ }
237
+
238
+ .weather-icon {
239
+ font-size: 18px;
240
+ }
241
+
242
+ .weather-loc {
243
+ flex: 1;
244
+ color: var(--text-primary);
245
+ }
246
+
247
+ .weather-temp {
248
+ font-weight: 600;
249
+ color: var(--accent-blue);
250
+ }
251
+
252
+ /* Utilities */
253
+ .loading-sm {
254
+ display: flex;
255
+ align-items: center;
256
+ justify-content: center;
257
+ padding: 20px;
258
+ }
259
+
260
+ .spinner-sm {
261
+ width: 20px;
262
+ height: 20px;
263
+ border: 2px solid var(--bg-tertiary);
264
+ border-top-color: var(--accent-blue);
265
+ border-radius: 50%;
266
+ animation: spin 1s linear infinite;
267
+ }
268
+
269
+ @keyframes spin {
270
+ to { transform: rotate(360deg); }
271
+ }
272
+
273
+ .error {
274
+ color: var(--accent-red);
275
+ padding: 10px;
276
+ text-align: center;
277
+ }
278
+
279
+ ::-webkit-scrollbar {
280
+ width: 6px;
281
+ }
282
+
283
+ ::-webkit-scrollbar-track {
284
+ background: var(--bg-primary);
285
+ }
286
+
287
+ ::-webkit-scrollbar-thumb {
288
+ background: var(--bg-tertiary);
289
+ border-radius: 3px;
290
+ }
291
+
292
+ /* Post-Export Edit Mode */
293
+ .edit-mode .widget-container {
294
+ cursor: move;
295
+ outline: 2px dashed #3b82f6;
296
+ outline-offset: -2px;
297
+ }
298
+
299
+ .edit-mode .widget-container:hover {
300
+ outline-color: #60a5fa;
301
+ }
302
+
303
+ .edit-mode .widget-container.dragging {
304
+ opacity: 0.8;
305
+ z-index: 1000;
306
+ }
307
+
308
+ .resize-handle-edit {
309
+ display: none;
310
+ position: absolute;
311
+ bottom: 0;
312
+ right: 0;
313
+ width: 16px;
314
+ height: 16px;
315
+ cursor: se-resize;
316
+ background: #3b82f6;
317
+ border-radius: 2px 0 0 0;
318
+ z-index: 10;
319
+ }
320
+
321
+ .edit-mode .resize-handle-edit {
322
+ display: block;
323
+ }
324
+
325
+ #edit-toggle {
326
+ position: fixed;
327
+ bottom: 20px;
328
+ right: 20px;
329
+ z-index: 9999;
330
+ padding: 8px 16px;
331
+ background: #1e293b;
332
+ color: white;
333
+ border: none;
334
+ border-radius: 6px;
335
+ cursor: pointer;
336
+ font-size: 13px;
337
+ font-weight: 500;
338
+ box-shadow: 0 2px 8px rgba(0,0,0,0.3);
339
+ }
340
+
341
+ #edit-toggle:hover {
342
+ background: #334155;
343
+ }
344
+
345
+ #edit-toggle.active {
346
+ background: #3b82f6;
347
+ }