@maudecode/cove 2026.2.6-3 → 2026.2.13
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/README.md +8 -5
- package/bin/cove.js +46 -0
- package/dist/assets/CanvasPanel-B6DhcK2j.js +12 -0
- package/dist/assets/index-B3H4uilc.js +426 -0
- package/dist/assets/index-CzHQWoDQ.css +1 -0
- package/dist/index.html +4 -3
- package/package.json +13 -5
- package/dist/assets/index-BhqyvNT-.css +0 -1
- package/dist/assets/index-DiGQZJ-4.js +0 -423
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="./docs/banner.jpg" alt="Cove" width="640">
|
|
2
|
+
<img src="./docs/public/banner.jpg" alt="Cove" width="640">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
- **File upload** — Drag & drop or paste images directly into chat
|
|
31
31
|
- **Message search** — Find anything with text search and date filters
|
|
32
32
|
- **Session management** — Create, rename, delete, and organize conversations
|
|
33
|
+
- **Command palette** — Press ⌘K to access any action instantly
|
|
33
34
|
|
|
34
35
|
### 🎛️ Operations Dashboard
|
|
35
36
|
- **Cron Jobs** — Create and manage scheduled tasks with visual editors
|
|
@@ -40,6 +41,8 @@
|
|
|
40
41
|
- **Devices** — Manage paired devices, approve pairing requests
|
|
41
42
|
- **Logs** — Real-time log viewer with level filtering and search
|
|
42
43
|
- **Debug** — RPC tester, event stream, connection diagnostics
|
|
44
|
+
- **Workspace** — Browse and edit agent configuration files with token counts
|
|
45
|
+
- **Usage** — Per-session analytics with timeline and cost breakdown
|
|
43
46
|
|
|
44
47
|
### 🎨 Customization
|
|
45
48
|
- **12 themes** — Light, Dark, Nord, Dracula, Catppuccin, Tokyo Night, and more
|
|
@@ -56,22 +59,22 @@
|
|
|
56
59
|
|
|
57
60
|
<details>
|
|
58
61
|
<summary><strong>Chat Interface</strong></summary>
|
|
59
|
-
<img src="./docs/chat.jpg" alt="Chat Interface" width="800">
|
|
62
|
+
<img src="./docs/public/chat.jpg" alt="Chat Interface" width="800">
|
|
60
63
|
</details>
|
|
61
64
|
|
|
62
65
|
<details>
|
|
63
66
|
<summary><strong>Server Stats</strong></summary>
|
|
64
|
-
<img src="./docs/server_stats.jpg" alt="Server Stats" width="800">
|
|
67
|
+
<img src="./docs/public/server_stats.jpg" alt="Server Stats" width="800">
|
|
65
68
|
</details>
|
|
66
69
|
|
|
67
70
|
<details>
|
|
68
71
|
<summary><strong>Settings</strong></summary>
|
|
69
|
-
<img src="./docs/cove_settings.jpg" alt="Cove Settings" width="800">
|
|
72
|
+
<img src="./docs/public/cove_settings.jpg" alt="Cove Settings" width="800">
|
|
70
73
|
</details>
|
|
71
74
|
|
|
72
75
|
<details>
|
|
73
76
|
<summary><strong>Configuration Editor</strong></summary>
|
|
74
|
-
<img src="./docs/config.jpg" alt="Configuration Editor" width="800">
|
|
77
|
+
<img src="./docs/public/config.jpg" alt="Configuration Editor" width="800">
|
|
75
78
|
</details>
|
|
76
79
|
|
|
77
80
|
## 🚀 Quick Start
|
package/bin/cove.js
CHANGED
|
@@ -19,6 +19,8 @@ const version = packageJson.version;
|
|
|
19
19
|
const args = process.argv.slice(2);
|
|
20
20
|
let port = 8080;
|
|
21
21
|
let open = false;
|
|
22
|
+
let gatewayHost = process.env.GATEWAY_HOST || "127.0.0.1";
|
|
23
|
+
let gatewayPort = process.env.GATEWAY_PORT || "18789";
|
|
22
24
|
|
|
23
25
|
for (let i = 0; i < args.length; i++) {
|
|
24
26
|
if (args[i] === "--port" || args[i] === "-p") {
|
|
@@ -41,6 +43,10 @@ Options:
|
|
|
41
43
|
-v, --version Show version number
|
|
42
44
|
-h, --help Show this help message
|
|
43
45
|
|
|
46
|
+
Environment Variables:
|
|
47
|
+
GATEWAY_HOST Gateway hostname for canvas proxy (default: 127.0.0.1)
|
|
48
|
+
GATEWAY_PORT Gateway port for canvas proxy (default: 18789)
|
|
49
|
+
|
|
44
50
|
Examples:
|
|
45
51
|
npx @maudecode/cove
|
|
46
52
|
npx @maudecode/cove --port 3000
|
|
@@ -77,6 +83,40 @@ function isPathSafe(requestedPath, baseDir) {
|
|
|
77
83
|
return fullPath === baseDir || fullPath.startsWith(baseDir + "/");
|
|
78
84
|
}
|
|
79
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Proxy /_canvas/* requests to gateway's canvas host
|
|
88
|
+
*/
|
|
89
|
+
async function handleCanvasProxy(req, res, urlPath) {
|
|
90
|
+
if (!urlPath.startsWith("/_canvas")) return false;
|
|
91
|
+
|
|
92
|
+
const targetPath = urlPath.replace("/_canvas", "") || "/";
|
|
93
|
+
const targetUrl = `http://${gatewayHost}:${gatewayPort}/__openclaw__/canvas${targetPath}`;
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
const response = await fetch(targetUrl, {
|
|
97
|
+
headers: {
|
|
98
|
+
Host: `${gatewayHost}:${gatewayPort}`,
|
|
99
|
+
Accept: "*/*",
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const contentType = response.headers.get("Content-Type") || "application/octet-stream";
|
|
104
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
105
|
+
|
|
106
|
+
res.writeHead(response.status, {
|
|
107
|
+
"Content-Type": contentType,
|
|
108
|
+
"Cache-Control": "no-store",
|
|
109
|
+
"Access-Control-Allow-Origin": "*",
|
|
110
|
+
});
|
|
111
|
+
res.end(buffer);
|
|
112
|
+
} catch (err) {
|
|
113
|
+
console.error("Canvas proxy error:", err.message);
|
|
114
|
+
res.writeHead(502);
|
|
115
|
+
res.end(`Canvas proxy error: ${err.message}`);
|
|
116
|
+
}
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
|
|
80
120
|
// Serve static files
|
|
81
121
|
const server = createServer(async (req, res) => {
|
|
82
122
|
try {
|
|
@@ -90,6 +130,11 @@ const server = createServer(async (req, res) => {
|
|
|
90
130
|
return;
|
|
91
131
|
}
|
|
92
132
|
|
|
133
|
+
// Canvas proxy
|
|
134
|
+
if (await handleCanvasProxy(req, res, urlPath)) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
93
138
|
// Decode URL and resolve path
|
|
94
139
|
const decodedPath = decodeURIComponent(urlPath);
|
|
95
140
|
let filePath = resolve(distDir, "." + decodedPath);
|
|
@@ -140,6 +185,7 @@ server.listen(port, () => {
|
|
|
140
185
|
🏖️ Cove v${version} is running!
|
|
141
186
|
|
|
142
187
|
Local: ${url}
|
|
188
|
+
Proxy: /_canvas/* → http://${gatewayHost}:${gatewayPort}/__openclaw__/canvas/*
|
|
143
189
|
|
|
144
190
|
Connect to your OpenClaw gateway to get started.
|
|
145
191
|
Press Ctrl+C to stop.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import{c as $,A as W,q as A,y as j,i as c,p as E,a as T,H as q,D as B,d as r,b as L,e as Y,M as R,f as G,g as X,h as J,j as ie,k as ce,l as Q,m as V,n as Z,o as ee,r as m,s as ue,t as de,u as ve,v as he,w as t,x as D,I as _,E as te,X as ne,C as ae,z as me,B as oe,F as fe,G as pe,J as we,L as se}from"./index-B3H4uilc.js";const xe=$("grip-horizontal",[["circle",{cx:"12",cy:"9",r:"1",key:"124mty"}],["circle",{cx:"19",cy:"9",r:"1",key:"1ruzo2"}],["circle",{cx:"5",cy:"9",r:"1",key:"1a8b28"}],["circle",{cx:"12",cy:"15",r:"1",key:"1e56xg"}],["circle",{cx:"19",cy:"15",r:"1",key:"1a92ep"}],["circle",{cx:"5",cy:"15",r:"1",key:"5r1jwy"}]]);const ge=$("maximize-2",[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"m21 3-7 7",key:"1l2asr"}],["path",{d:"m3 21 7-7",key:"tjx5ai"}],["path",{d:"M9 21H3v-6",key:"wtvkvv"}]]);const ye=$("minimize-2",[["path",{d:"m14 10 7-7",key:"oa77jy"}],["path",{d:"M20 10h-6V4",key:"mjg0md"}],["path",{d:"m3 21 7-7",key:"tjx5ai"}],["path",{d:"M4 14h6v6",key:"rmj7iw"}]]);const be=$("picture-in-picture-2",[["path",{d:"M21 9V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v10c0 1.1.9 2 2 2h4",key:"daa4of"}],["rect",{width:"10",height:"7",x:"12",y:"13",rx:"2",key:"1nb8gs"}]]);function Me(){const I=W(!1),a=W(!1),d=W({x:0,y:0,panelX:0,panelY:0}),l=W({x:0,y:0,width:0,height:0,panelX:0,panelY:0}),P=W(""),O=A(s=>{if(s.target.closest("button"))return;s.preventDefault(),I.current=!0,X.value=!0;const u=J(s);d.current={x:u.x,y:u.y,panelX:E.value,panelY:T.value},document.body.style.cursor="grabbing",document.body.style.userSelect="none"},[]),U=A((s,u)=>{s.preventDefault(),"stopPropagation"in s&&s.stopPropagation(),a.current=!0,X.value=!0,P.current=u;const v=J(s);l.current={x:v.x,y:v.y,width:L.value,height:Y.value,panelX:E.value,panelY:T.value};const z={n:"n-resize",s:"s-resize",e:"e-resize",w:"w-resize",ne:"ne-resize",nw:"nw-resize",se:"se-resize",sw:"sw-resize"};document.body.style.cursor=z[u]||"nwse-resize",document.body.style.userSelect="none"},[]),N=A(s=>{s.preventDefault(),a.current=!0,X.value=!0,l.current={x:s.clientX,y:s.clientY,width:L.value,height:Y.value,panelX:E.value,panelY:T.value},document.body.style.userSelect="none";const u=window.innerWidth*ie,v=window.innerHeight*ce,z=S=>{if(r.value==="left"){const n=S.clientX-l.current.x;L.value=Math.min(u,Math.max(R,l.current.width+n))}else if(r.value==="right"){const n=l.current.x-S.clientX;L.value=Math.min(u,Math.max(R,l.current.width+n))}else if(r.value==="top"){const n=S.clientY-l.current.y;Y.value=Math.min(v,Math.max(G,l.current.height+n))}},H=()=>{a.current=!1,X.value=!1,document.body.style.userSelect="",document.removeEventListener("mousemove",z),document.removeEventListener("mouseup",H)};document.addEventListener("mousemove",z),document.addEventListener("mouseup",H)},[]);return j(()=>{const s=(n,f)=>{if(I.current){const y=window.innerWidth,e=window.innerHeight;if(c.value){const o=n-d.current.x,b=f-d.current.y,p=d.current.panelX+o,M=d.current.panelY+b,h=200;E.value=Math.max(0,Math.min(p,y-h)),T.value=Math.max(0,Math.min(M,e-q));return}if(n<B)r.value="left";else if(n>y-B)r.value="right";else if(f<B)r.value="top";else{if(r.value!=="floating")E.value=Math.max(0,Math.min(n-L.value/2,y-L.value)),T.value=Math.max(0,Math.min(f-q/2,e-Y.value)),d.current={x:n,y:f,panelX:E.value,panelY:T.value};else{const o=n-d.current.x,b=f-d.current.y,p=d.current.panelX+o,M=d.current.panelY+b;E.value=Math.max(0,Math.min(p,y-L.value)),T.value=Math.max(0,Math.min(M,e-Y.value))}r.value="floating"}}if(a.current&&r.value==="floating"){const y=P.current,{x:e,y:o,width:b,height:p}=l.current,M=window.innerWidth,h=window.innerHeight;let i=b,k=p,C=l.current.panelX,w=l.current.panelY;if(y.includes("e")&&(i=Math.max(R,b+(n-e))),y.includes("w")){const x=e-n,g=b+x;g>=R&&(i=g,C=l.current.panelX-x)}if(y.includes("s")&&(k=Math.max(G,p+(f-o))),y.includes("n")){const x=o-f,g=p+x;g>=G&&(k=g,w=l.current.panelY-x)}C+i>M&&(i=M-C),w+k>h&&(k=h-w),C<0&&(i+=C,C=0),w<0&&(k+=w,w=0),L.value=Math.max(R,i),Y.value=Math.max(G,k),E.value=Math.max(0,C),T.value=Math.max(0,w)}},u=()=>{(I.current||a.current)&&(I.current=!1,a.current=!1,X.value=!1,document.body.style.cursor="",document.body.style.userSelect="")},v=n=>s(n.clientX,n.clientY),z=n=>{if(n.touches.length===1){const f=n.touches[0];s(f.clientX,f.clientY)}},H=()=>u(),S=()=>u();return document.addEventListener("mousemove",v),document.addEventListener("mouseup",H),document.addEventListener("touchmove",z,{passive:!1}),document.addEventListener("touchend",S),()=>{document.removeEventListener("mousemove",v),document.removeEventListener("mouseup",H),document.removeEventListener("touchmove",z),document.removeEventListener("touchend",S)}},[]),{handleDragStart:O,handleResizeStart:U,handleDockedResizeStart:N}}function ze(){if(V.value&&!m.value){if(pe.value)return;m.value=!0,c.value=!1}else!V.value&&m.value&&(m.value=!1)}const re=we(typeof window<"u"&&window.innerWidth<se);typeof window<"u"&&window.addEventListener("resize",()=>{re.value=window.innerWidth<se});const Se=100;function De(){const{handleDragStart:I,handleResizeStart:a,handleDockedResizeStart:d}=Me(),[l,P]=Q(0),[O,U]=Q(!1),N=W(0),s=W(null),u=W(null);j(()=>V.subscribe(ze),[]),j(()=>Z.subscribe(e=>{if(!e)return;const{js:o,resolve:b,reject:p}=e;Z.value=null;const M=s.current;if(!M?.contentWindow){p("No iframe available for eval");return}try{const h=M.contentWindow.eval(o);b(h)}catch(h){p(String(h))}}),[]),j(()=>ee.subscribe(e=>{if(!e)return;const{maxWidth:o,quality:b,outputFormat:p,resolve:M,reject:h}=e;ee.value=null;try{const i=u.current;if(i&&i.complete){const w=document.createElement("canvas");let x=i.naturalWidth||i.width||100,g=i.naturalHeight||i.height||100;if(x>o||g>o){const K=o/Math.max(x,g);x=Math.round(x*K),g=Math.round(g*K)}w.width=x,w.height=g;const F=w.getContext("2d");if(F){F.drawImage(i,0,0,x,g);const K=p==="png"?"image/png":"image/jpeg",le=w.toDataURL(K,b);M(le);return}}const k=s.current;if(!k?.contentWindow){h("No canvas content available for snapshot (no img or iframe ref)");return}if(!k.contentDocument){h("Cannot access iframe document (cross-origin?)");return}h("HTML snapshot not yet implemented - use images for now")}catch(i){h(`Snapshot failed: ${i}`)}}),[]),j(()=>{const e=o=>{o.key==="Escape"&&m.value&&(m.value=!1),(o.metaKey||o.ctrlKey)&&o.shiftKey&&o.key==="c"&&(o.preventDefault(),m.value=!m.value)};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[]);const v=ue.value,z=de.value,H=ve.value,S=he.value;if(!m.value)return null;const n=e=>{N.current=e.touches[0].clientY,U(!0)},f=e=>{if(!O)return;const o=e.touches[0].clientY-N.current;P(Math.max(0,o))},y=()=>{U(!1),l>Se&&(m.value=!1),P(0)};return re.value?t("div",{class:`fixed inset-x-0 bottom-0 z-50 bg-[var(--color-bg-surface)] rounded-t-2xl border-t border-[var(--color-border)] shadow-soft-xl flex flex-col ${O?"":"transition-transform duration-200"}`,style:{height:"70vh",maxHeight:"70vh",transform:`translateY(${l}px)`},children:[t("div",{class:"flex flex-col items-center pt-2 pb-1 cursor-grab active:cursor-grabbing touch-none",onTouchStart:n,onTouchMove:f,onTouchEnd:y,children:t("div",{class:"w-10 h-1 bg-[var(--color-border)] rounded-full"})}),t("div",{class:"flex items-center justify-between px-4 py-2 border-b border-[var(--color-border)]",children:[t("span",{class:"text-sm font-medium text-[var(--color-text-primary)]",children:D("canvas.title")}),t("div",{class:"flex items-center gap-1",children:[v&&t(_,{icon:t(te,{}),label:D("canvas.openUrlInNewTab"),size:"sm",onClick:()=>window.open(v,"_blank")}),t(_,{icon:t(ne,{}),label:D("canvas.close"),size:"sm",onClick:()=>m.value=!1})]})]}),t("div",{class:"flex-1 overflow-hidden",children:t(ae,{url:v,blobUrl:z,contentType:H,content:S,iframeRef:s,imgRef:u})})]}):t("div",{class:`
|
|
2
|
+
fixed z-50
|
|
3
|
+
bg-[var(--color-bg-surface)]
|
|
4
|
+
shadow-soft-xl
|
|
5
|
+
flex flex-col
|
|
6
|
+
overflow-hidden
|
|
7
|
+
animate-[fade-in-scale_150ms_ease-out]
|
|
8
|
+
${c.value?"rounded-full border-0":"rounded-xl border border-[var(--color-border)]"}
|
|
9
|
+
`,style:{...me.value,position:"fixed"},children:[t("div",{class:`
|
|
10
|
+
flex items-center gap-2 px-3 cursor-grab active:cursor-grabbing select-none shrink-0
|
|
11
|
+
${c.value?"py-2":"py-2 border-b border-[var(--color-border)]"}
|
|
12
|
+
`,style:{height:`${q}px`},onMouseDown:I,onTouchStart:I,children:[t(xe,{class:"w-4 h-4 text-[var(--color-text-muted)] shrink-0"}),t("span",{class:"text-sm font-medium text-[var(--color-text-primary)] truncate flex-1",children:D("canvas.title")}),t("div",{class:"flex items-center gap-1",children:[v&&!c.value&&t(_,{icon:t(te,{}),label:D("canvas.openUrlInNewTab"),size:"sm",onClick:()=>window.open(v,"_blank")}),!c.value&&t(_,{icon:t(be,{}),label:D("canvas.openCanvasTab"),size:"sm",onClick:()=>{window.open("/canvas","_blank"),m.value=!1}}),t(_,{icon:c.value?t(ge,{}):t(ye,{}),label:c.value?D("canvas.maximize"):D("canvas.minimize"),size:"sm",onClick:()=>{c.value?r.value=oe.value:(oe.value=r.value,r.value!=="floating"&&(E.value=window.innerWidth-220,T.value=window.innerHeight-60),r.value="floating"),c.value=!c.value}}),t(_,{icon:t(ne,{}),label:D("canvas.close"),size:"sm",onClick:()=>m.value=!1})]})]}),!c.value&&t("div",{class:"flex-1 overflow-hidden relative",children:[t(ae,{url:v,blobUrl:z,contentType:H,content:S,iframeRef:s,imgRef:u}),X.value&&t("div",{class:"absolute inset-0 z-10"})]}),r.value==="floating"&&!c.value&&t(fe,{children:[t("div",{class:"absolute bottom-0 right-0 w-4 h-4 cursor-se-resize z-10 touch-none",onMouseDown:e=>a(e,"se"),onTouchStart:e=>a(e,"se")}),t("div",{class:"absolute bottom-0 left-0 w-4 h-4 cursor-sw-resize z-10 touch-none",onMouseDown:e=>a(e,"sw"),onTouchStart:e=>a(e,"sw")}),t("div",{class:"absolute top-11 right-0 w-4 h-4 cursor-ne-resize z-10 touch-none",onMouseDown:e=>a(e,"ne"),onTouchStart:e=>a(e,"ne")}),t("div",{class:"absolute top-11 left-0 w-4 h-4 cursor-nw-resize z-10 touch-none",onMouseDown:e=>a(e,"nw"),onTouchStart:e=>a(e,"nw")}),t("div",{class:"absolute right-0 w-2 cursor-e-resize touch-none",style:{top:"60px",height:"calc(100% - 76px)"},onMouseDown:e=>a(e,"e"),onTouchStart:e=>a(e,"e")}),t("div",{class:"absolute left-0 w-2 cursor-w-resize touch-none",style:{top:"60px",height:"calc(100% - 76px)"},onMouseDown:e=>a(e,"w"),onTouchStart:e=>a(e,"w")}),t("div",{class:"absolute bottom-0 h-2 cursor-s-resize touch-none",style:{left:"16px",width:"calc(100% - 32px)"},onMouseDown:e=>a(e,"s"),onTouchStart:e=>a(e,"s")})]}),r.value==="left"&&!c.value&&t("div",{class:"absolute right-0 top-0 w-2 h-full cursor-e-resize",onMouseDown:d}),r.value==="right"&&!c.value&&t("div",{class:"absolute left-0 top-0 w-2 h-full cursor-w-resize",onMouseDown:d}),r.value==="top"&&!c.value&&t("div",{class:"absolute left-0 bottom-0 w-full h-2 cursor-s-resize",onMouseDown:d})]})}export{De as CanvasPanel};
|