@maudecode/cove 1.0.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 (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +177 -0
  3. package/bin/cove.js +157 -0
  4. package/dist/apple-touch-icon.png +0 -0
  5. package/dist/assets/geist-sans-latin-400-normal-BOaIZNA2.woff +0 -0
  6. package/dist/assets/geist-sans-latin-400-normal-gapTbOY8.woff2 +0 -0
  7. package/dist/assets/geist-sans-latin-500-normal-CN2lyvyL.woff +0 -0
  8. package/dist/assets/geist-sans-latin-500-normal-uokXdC-Q.woff2 +0 -0
  9. package/dist/assets/geist-sans-latin-600-normal-CA1yjETN.woff +0 -0
  10. package/dist/assets/geist-sans-latin-600-normal-DFOURf8L.woff2 +0 -0
  11. package/dist/assets/index-ChRK8BG1.js +417 -0
  12. package/dist/assets/index-NMo4OSLa.css +1 -0
  13. package/dist/assets/inter-cyrillic-400-normal-HOLc17fK.woff +0 -0
  14. package/dist/assets/inter-cyrillic-400-normal-obahsSVq.woff2 +0 -0
  15. package/dist/assets/inter-cyrillic-500-normal-BasfLYem.woff2 +0 -0
  16. package/dist/assets/inter-cyrillic-500-normal-CxZf_p3X.woff +0 -0
  17. package/dist/assets/inter-cyrillic-600-normal-4D_pXhcN.woff +0 -0
  18. package/dist/assets/inter-cyrillic-600-normal-CWCymEST.woff2 +0 -0
  19. package/dist/assets/inter-cyrillic-ext-400-normal-BQZuk6qB.woff2 +0 -0
  20. package/dist/assets/inter-cyrillic-ext-400-normal-DQukG94-.woff +0 -0
  21. package/dist/assets/inter-cyrillic-ext-500-normal-B0yAr1jD.woff2 +0 -0
  22. package/dist/assets/inter-cyrillic-ext-500-normal-BmqWE9Dz.woff +0 -0
  23. package/dist/assets/inter-cyrillic-ext-600-normal-Bcila6Z-.woff +0 -0
  24. package/dist/assets/inter-cyrillic-ext-600-normal-Dfes3d0z.woff2 +0 -0
  25. package/dist/assets/inter-greek-400-normal-B4URO6DV.woff2 +0 -0
  26. package/dist/assets/inter-greek-400-normal-q2sYcFCs.woff +0 -0
  27. package/dist/assets/inter-greek-500-normal-BIZE56-Y.woff2 +0 -0
  28. package/dist/assets/inter-greek-500-normal-Xzm54t5V.woff +0 -0
  29. package/dist/assets/inter-greek-600-normal-BZpKdvQh.woff +0 -0
  30. package/dist/assets/inter-greek-600-normal-plRanbMR.woff2 +0 -0
  31. package/dist/assets/inter-greek-ext-400-normal-DGGRlc-M.woff2 +0 -0
  32. package/dist/assets/inter-greek-ext-400-normal-KugGGMne.woff +0 -0
  33. package/dist/assets/inter-greek-ext-500-normal-2j5mBUwD.woff +0 -0
  34. package/dist/assets/inter-greek-ext-500-normal-C4iEst2y.woff2 +0 -0
  35. package/dist/assets/inter-greek-ext-600-normal-B8X0CLgF.woff +0 -0
  36. package/dist/assets/inter-greek-ext-600-normal-DRtmH8MT.woff2 +0 -0
  37. package/dist/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
  38. package/dist/assets/inter-latin-400-normal-CyCys3Eg.woff +0 -0
  39. package/dist/assets/inter-latin-500-normal-BL9OpVg8.woff +0 -0
  40. package/dist/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
  41. package/dist/assets/inter-latin-600-normal-CiBQ2DWP.woff +0 -0
  42. package/dist/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
  43. package/dist/assets/inter-latin-ext-400-normal-77YHD8bZ.woff +0 -0
  44. package/dist/assets/inter-latin-ext-400-normal-C1nco2VV.woff2 +0 -0
  45. package/dist/assets/inter-latin-ext-500-normal-BxGbmqWO.woff +0 -0
  46. package/dist/assets/inter-latin-ext-500-normal-CV4jyFjo.woff2 +0 -0
  47. package/dist/assets/inter-latin-ext-600-normal-CIVaiw4L.woff +0 -0
  48. package/dist/assets/inter-latin-ext-600-normal-D2bJ5OIk.woff2 +0 -0
  49. package/dist/assets/inter-vietnamese-400-normal-Bbgyi5SW.woff +0 -0
  50. package/dist/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
  51. package/dist/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
  52. package/dist/assets/inter-vietnamese-500-normal-mJboJaSs.woff +0 -0
  53. package/dist/assets/inter-vietnamese-600-normal-BuLX-rYi.woff +0 -0
  54. package/dist/assets/inter-vietnamese-600-normal-Cc8MFFhd.woff2 +0 -0
  55. package/dist/assets/opendyslexic-latin-400-normal-Cv3YY6GF.woff +0 -0
  56. package/dist/assets/opendyslexic-latin-400-normal-nUhe5EwG.woff2 +0 -0
  57. package/dist/cove-icon.png +0 -0
  58. package/dist/favicon-16x16.png +0 -0
  59. package/dist/favicon-32x32.png +0 -0
  60. package/dist/favicon.svg +3 -0
  61. package/dist/index.html +90 -0
  62. package/package.json +88 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MaudeCode
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,177 @@
1
+ <p align="center">
2
+ <img src="./docs/banner.jpg" alt="Cove" width="640">
3
+ </p>
4
+
5
+ <p align="center">
6
+ A beautiful, full-featured WebUI for <a href="https://github.com/openclaw/openclaw">OpenClaw</a>
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="#-features">Features</a> •
11
+ <a href="#-quick-start">Quick Start</a> •
12
+ <a href="#-deployment">Deployment</a> •
13
+ <a href="#-development">Development</a>
14
+ </p>
15
+
16
+ ---
17
+
18
+ ## ✨ Features
19
+
20
+ ### 💬 Chat
21
+ - **Real-time streaming** — Watch responses flow in with live markdown rendering
22
+ - **Tool call visualization** — See what your assistant is doing with expandable tool details
23
+ - **Syntax highlighting** — Beautiful code blocks with one-click copy
24
+ - **File upload** — Drag & drop or paste images directly into chat
25
+ - **Message search** — Find anything with text search and date filters
26
+ - **Session management** — Create, rename, delete, and organize conversations
27
+
28
+ ### 🎛️ Operations Dashboard
29
+ - **Cron Jobs** — Create and manage scheduled tasks with visual editors
30
+ - **Config Editor** — Full configuration editing with schema validation and diff view
31
+ - **Sessions Admin** — View all sessions with stats, filters, and bulk actions
32
+ - **Channels** — Monitor all messaging channels (Telegram, Discord, Signal, etc.)
33
+ - **Skills Browser** — Browse local and [ClawHub](https://clawhub.ai) skills, install with one click
34
+ - **Devices** — Manage paired devices, approve pairing requests
35
+ - **Logs** — Real-time log viewer with level filtering and search
36
+ - **Debug** — RPC tester, event stream, connection diagnostics
37
+
38
+ ### 🎨 Customization
39
+ - **6 themes** — Light, Dark, Nord, Dracula, Solarized Light/Dark
40
+ - **System sync** — Automatically switches with your OS preference
41
+ - **Font options** — System, Geist, Inter, JetBrains Mono, OpenDyslexic
42
+ - **Adjustable sizing** — Small, medium, or large text
43
+
44
+ ### 🔒 Security
45
+ - **Exec approval** — Interactive modal for shell command approvals
46
+ - **Secure storage** — Credentials stored in browser localStorage
47
+ - **No telemetry** — Your data stays on your gateway
48
+
49
+ ## 🚀 Quick Start
50
+
51
+ ### Option 1: Docker (Recommended)
52
+
53
+ ```bash
54
+ docker run -d -p 8080:8080 ghcr.io/maudecode/cove:latest
55
+ ```
56
+
57
+ Then open http://localhost:8080 and connect to your OpenClaw gateway.
58
+
59
+ ### Option 2: Static Hosting
60
+
61
+ Download the latest release and serve the `dist/` folder with any static file server:
62
+
63
+ ```bash
64
+ # Using Python
65
+ cd dist && python -m http.server 8080
66
+
67
+ # Using Node
68
+ npx serve dist -p 8080
69
+
70
+ # Using Caddy
71
+ caddy file-server --root dist --listen :8080
72
+ ```
73
+
74
+ ### Option 3: Build from Source
75
+
76
+ ```bash
77
+ git clone https://github.com/MaudeCode/cove.git
78
+ cd cove
79
+ bun install
80
+ bun run build
81
+ ```
82
+
83
+ The built files will be in `dist/`.
84
+
85
+ ## 📱 Connecting to Your Gateway
86
+
87
+ 1. Open Cove in your browser
88
+ 2. Enter your OpenClaw gateway URL (e.g., `wss://your-gateway.example.com`)
89
+ 3. Choose authentication method:
90
+ - **Token** — Use your gateway token
91
+ - **Password** — Use the configured password
92
+ 4. Click Connect
93
+
94
+ **First time?** The onboarding wizard will guide you through setup.
95
+
96
+ ## 🏗️ Development
97
+
98
+ ```bash
99
+ # Install dependencies
100
+ bun install
101
+
102
+ # Start dev server
103
+ bun run dev
104
+
105
+ # Run all checks (lint, format, typecheck, unused exports)
106
+ bun run check
107
+
108
+ # Build for production
109
+ bun run build
110
+ ```
111
+
112
+ ### Project Structure
113
+
114
+ ```
115
+ src/
116
+ ├── components/
117
+ │ ├── ui/ # Reusable primitives (Button, Modal, Card, etc.)
118
+ │ ├── chat/ # Chat interface components
119
+ │ └── layout/ # App shell, sidebar, navigation
120
+ ├── views/ # Page components (ChatView, CronView, etc.)
121
+ ├── lib/ # Core utilities (gateway client, i18n, theme)
122
+ ├── signals/ # Preact Signals state management
123
+ ├── hooks/ # Custom Preact hooks
124
+ ├── types/ # TypeScript definitions
125
+ └── locales/ # Translation files
126
+ ```
127
+
128
+ ### Tech Stack
129
+
130
+ | Technology | Purpose |
131
+ |------------|---------|
132
+ | [Preact](https://preactjs.com/) | UI framework (~3KB) |
133
+ | [Preact Signals](https://preactjs.com/guide/v10/signals/) | Reactive state |
134
+ | [Tailwind CSS v4](https://tailwindcss.com/) | Styling |
135
+ | [Vite](https://vitejs.dev/) | Build tooling |
136
+ | [TypeScript](https://www.typescriptlang.org/) | Type safety |
137
+ | [marked](https://marked.js.org/) | Markdown rendering |
138
+ | [Prism](https://prismjs.com/) | Syntax highlighting |
139
+
140
+ ## 🤝 Contributing
141
+
142
+ Contributions are welcome! Please:
143
+
144
+ 1. Fork the repository
145
+ 2. Create a feature branch (`git checkout -b feat/amazing-feature`)
146
+ 3. Make your changes
147
+ 4. Run checks (`bun run check`)
148
+ 5. Commit with conventional commits (`feat:`, `fix:`, `docs:`, etc.)
149
+ 6. Open a Pull Request
150
+
151
+ See [ROADMAP.md](./ROADMAP.md) for planned features and areas needing help.
152
+
153
+ ## 📋 Requirements
154
+
155
+ - **OpenClaw gateway** v0.9+ running and accessible
156
+ - **Modern browser** with WebSocket support (Chrome, Firefox, Safari, Edge)
157
+
158
+ ## 🐛 Known Limitations
159
+
160
+ - File uploads are image-only (PDF, text files coming soon)
161
+ - Multi-tab sync for user messages requires page refresh
162
+ - Assistant-generated images display as file paths (gateway enhancement planned)
163
+
164
+ ## 📄 License
165
+
166
+ MIT — see [LICENSE](./LICENSE) for details.
167
+
168
+ ## 🔗 Links
169
+
170
+ - [OpenClaw Documentation](https://docs.openclaw.ai)
171
+ - [OpenClaw GitHub](https://github.com/openclaw/openclaw)
172
+ - [ClawHub Skills](https://clawhub.ai)
173
+ - [Discord Community](https://discord.com/invite/clawd)
174
+
175
+ ---
176
+
177
+ Built with 🐄 by [Maude](https://github.com/MaudeCode) and [Kilian](https://github.com/kiliantyler)
package/bin/cove.js ADDED
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { createServer } from "node:http";
4
+ import { readFile, stat } from "node:fs/promises";
5
+ import { join, extname, resolve } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import { exec } from "node:child_process";
8
+
9
+ const __dirname = fileURLToPath(new URL(".", import.meta.url));
10
+ const distDir = resolve(__dirname, "..", "dist");
11
+
12
+ // Get version from package.json
13
+ const packageJson = JSON.parse(
14
+ await readFile(resolve(__dirname, "..", "package.json"), "utf-8")
15
+ );
16
+ const version = packageJson.version;
17
+
18
+ // Parse CLI arguments
19
+ const args = process.argv.slice(2);
20
+ let port = 8080;
21
+ let open = false;
22
+
23
+ for (let i = 0; i < args.length; i++) {
24
+ if (args[i] === "--port" || args[i] === "-p") {
25
+ port = parseInt(args[i + 1], 10) || 8080;
26
+ i++;
27
+ } else if (args[i] === "--open" || args[i] === "-o") {
28
+ open = true;
29
+ } else if (args[i] === "--version" || args[i] === "-v") {
30
+ console.log(`cove v${version}`);
31
+ process.exit(0);
32
+ } else if (args[i] === "--help" || args[i] === "-h") {
33
+ console.log(`
34
+ Cove v${version} - WebUI for OpenClaw
35
+
36
+ Usage: npx @maudecode/cove [options]
37
+
38
+ Options:
39
+ -p, --port <port> Port to listen on (default: 8080)
40
+ -o, --open Open browser automatically
41
+ -v, --version Show version number
42
+ -h, --help Show this help message
43
+
44
+ Examples:
45
+ npx @maudecode/cove
46
+ npx @maudecode/cove --port 3000
47
+ npx @maudecode/cove --port 3000 --open
48
+ `);
49
+ process.exit(0);
50
+ }
51
+ }
52
+
53
+ // MIME types
54
+ const mimeTypes = {
55
+ ".html": "text/html",
56
+ ".js": "application/javascript",
57
+ ".css": "text/css",
58
+ ".json": "application/json",
59
+ ".png": "image/png",
60
+ ".jpg": "image/jpeg",
61
+ ".jpeg": "image/jpeg",
62
+ ".gif": "image/gif",
63
+ ".svg": "image/svg+xml",
64
+ ".ico": "image/x-icon",
65
+ ".woff": "font/woff",
66
+ ".woff2": "font/woff2",
67
+ ".ttf": "font/ttf",
68
+ ".txt": "text/plain",
69
+ };
70
+
71
+ /**
72
+ * Check if a path is within the allowed directory (prevent path traversal)
73
+ */
74
+ function isPathSafe(requestedPath, baseDir) {
75
+ const fullPath = resolve(requestedPath);
76
+ // Ensure resolved path starts with baseDir
77
+ return fullPath === baseDir || fullPath.startsWith(baseDir + "/");
78
+ }
79
+
80
+ // Serve static files
81
+ const server = createServer(async (req, res) => {
82
+ try {
83
+ let urlPath = req.url?.split("?")[0] || "/";
84
+ if (urlPath === "/") urlPath = "/index.html";
85
+
86
+ // Health check endpoint
87
+ if (urlPath === "/health") {
88
+ res.writeHead(200, { "Content-Type": "text/plain" });
89
+ res.end("OK");
90
+ return;
91
+ }
92
+
93
+ // Decode URL and resolve path
94
+ const decodedPath = decodeURIComponent(urlPath);
95
+ let filePath = resolve(distDir, "." + decodedPath);
96
+
97
+ // Security: Ensure path doesn't escape dist directory
98
+ if (!isPathSafe(filePath, distDir)) {
99
+ res.writeHead(403);
100
+ res.end("Forbidden");
101
+ return;
102
+ }
103
+
104
+ // Check if file exists, otherwise serve index.html (SPA routing)
105
+ try {
106
+ const fileStat = await stat(filePath);
107
+ if (fileStat.isDirectory()) {
108
+ filePath = join(filePath, "index.html");
109
+ }
110
+ } catch {
111
+ filePath = join(distDir, "index.html");
112
+ }
113
+
114
+ const ext = extname(filePath);
115
+ const contentType = mimeTypes[ext] || "application/octet-stream";
116
+ const content = await readFile(filePath);
117
+
118
+ res.writeHead(200, { "Content-Type": contentType });
119
+ res.end(content);
120
+ } catch (err) {
121
+ res.writeHead(500);
122
+ res.end("Internal Server Error");
123
+ }
124
+ });
125
+
126
+ // Handle server errors
127
+ server.on("error", (err) => {
128
+ if (err.code === "EADDRINUSE") {
129
+ console.error(`\n❌ Port ${port} is already in use.\n`);
130
+ console.error(` Try a different port: npx @maudecode/cove --port ${port + 1}\n`);
131
+ process.exit(1);
132
+ }
133
+ console.error("Server error:", err);
134
+ process.exit(1);
135
+ });
136
+
137
+ server.listen(port, () => {
138
+ const url = `http://localhost:${port}`;
139
+ console.log(`
140
+ 🏖️ Cove v${version} is running!
141
+
142
+ Local: ${url}
143
+
144
+ Connect to your OpenClaw gateway to get started.
145
+ Press Ctrl+C to stop.
146
+ `);
147
+
148
+ if (open) {
149
+ const cmd =
150
+ process.platform === "darwin"
151
+ ? "open"
152
+ : process.platform === "win32"
153
+ ? "start"
154
+ : "xdg-open";
155
+ exec(`${cmd} ${url}`);
156
+ }
157
+ });
Binary file