opencami 1.7.0 → 1.8.3

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 (83) hide show
  1. package/README.md +167 -7
  2. package/bin/opencami.js +15 -6
  3. package/dist/client/assets/{CSPContext-a-MQmQQt.js → CSPContext-DeJH85nm.js} +1 -1
  4. package/dist/client/assets/{DirectionContext-DRcND-Cm.js → DirectionContext-CxhRpXkm.js} +1 -1
  5. package/dist/client/assets/_sessionKey-CQE0brGK.js +23 -0
  6. package/dist/client/assets/agents-CMTFd_sG.js +2 -0
  7. package/dist/client/assets/agents-screen-BNQGEqcW.js +1 -0
  8. package/dist/client/assets/bots-B6oGzCxP.js +2 -0
  9. package/dist/client/assets/bots-screen-Be3cfGgq.js +1 -0
  10. package/dist/client/assets/button-D9Plv7hu.js +1 -0
  11. package/dist/client/assets/composite-B2KCZKKL.js +1 -0
  12. package/dist/client/assets/{connect-BX1MWO82.js → connect-DuJfnyNK.js} +1 -1
  13. package/dist/client/assets/dashboard-00GpXm5V.js +1 -0
  14. package/dist/client/assets/event-DD8Cz4O9.js +1 -0
  15. package/dist/client/assets/file-explorer-screen-CxwemBES.js +1 -0
  16. package/dist/client/assets/files-DyBJVXBu.js +2 -0
  17. package/dist/client/assets/{index-BlC2sH55.js → index-DtGzE-ea.js} +1 -1
  18. package/dist/client/assets/{index-Dg0mbvtv.js → index-Yo5UhdZV.js} +1 -1
  19. package/dist/client/assets/keyboard-shortcuts-dialog-BZwd-iyV.js +1 -0
  20. package/dist/client/assets/{main-CEuT8-Qi.js → main-CgwdHc9W.js} +16 -8
  21. package/dist/client/assets/{markdown-DKD6ZLRJ.js → markdown-DtWnt4NA.js} +1 -1
  22. package/dist/client/assets/memory-l756yiNq.js +2 -0
  23. package/dist/client/assets/memory-screen-BQtVRuzE.js +1 -0
  24. package/dist/client/assets/menu-BsS6CDf_.js +1 -0
  25. package/dist/client/assets/{opencami-logo-DA69yVKc.js → opencami-logo-Bmge6-FB.js} +1 -1
  26. package/dist/client/assets/popupStateMapping-D0ZbJR_o.js +1 -0
  27. package/dist/client/assets/{proxy-Cawf6X0W.js → proxy-CYZeDXoy.js} +1 -1
  28. package/dist/client/assets/{react-K9goXsVv.js → react-DODKNyyU.js} +1 -1
  29. package/dist/client/assets/search-dialog-DW91SK30.js +1 -0
  30. package/dist/client/assets/session-export-dialog-CliO9Ob-.js +1 -0
  31. package/dist/client/assets/settings-dialog-C1u52aju.js +1 -0
  32. package/dist/client/assets/skills-8T_avaVb.js +2 -0
  33. package/dist/client/assets/{skills-panel-DFL-3BRH.js → skills-panel-DSiH-DLs.js} +1 -1
  34. package/dist/client/assets/styles-DvaLh0o1.css +1 -0
  35. package/dist/client/assets/switch-DbgQPO6i.js +1 -0
  36. package/dist/client/assets/tabs-BsAvZnlD.js +1 -0
  37. package/dist/client/assets/tooltip-DLmutB5C.js +1 -0
  38. package/dist/client/assets/use-file-explorer-state-Cg_yDYJl.js +12 -0
  39. package/dist/client/assets/useBaseUiId-KQTzRPLp.js +1 -0
  40. package/dist/client/assets/useCompositeItem-BPY2_hF_.js +1 -0
  41. package/dist/client/assets/{useControlled-Cl9XA2_f.js → useControlled-B5pEEz2V.js} +1 -1
  42. package/dist/client/assets/{useMutation-C5bTdeC1.js → useMutation-BsQD6FKe.js} +1 -1
  43. package/dist/client/assets/useQuery-CmAJuY2W.js +1 -0
  44. package/dist/client/assets/visuallyHidden-COI6QeQH.js +1 -0
  45. package/dist/client/sw.js +5 -164
  46. package/dist/server/assets/{_sessionKey-BBG3ZUlo.js → _sessionKey-C9o7YfxA.js} +878 -755
  47. package/dist/server/assets/_tanstack-start-manifest_v-BMCAWon2.js +4 -0
  48. package/dist/server/assets/dashboard-GCKodTiJ.js +214 -0
  49. package/dist/server/assets/{index-BgMPaOsU.js → index-Bw-bA_2M.js} +4 -3
  50. package/dist/server/assets/{router-Bl2uabfY.js → router-DCjikH21.js} +704 -207
  51. package/dist/server/assets/{search-dialog-BtSQW9SR.js → search-dialog-BnwiXpdA.js} +5 -4
  52. package/dist/server/assets/settings-dialog-ClKFnZ1x.js +1511 -0
  53. package/dist/server/server.js +2 -2
  54. package/package.json +1 -1
  55. package/dist/client/assets/_sessionKey-BAmpzUOP.js +0 -23
  56. package/dist/client/assets/agents-BkeWu_3a.js +0 -2
  57. package/dist/client/assets/agents-screen-Cb76bcxn.js +0 -1
  58. package/dist/client/assets/bots-CyJwr-JU.js +0 -2
  59. package/dist/client/assets/bots-screen-CzNjLsQH.js +0 -1
  60. package/dist/client/assets/button-DNC5N25i.js +0 -1
  61. package/dist/client/assets/composite-Bliqcmg4.js +0 -1
  62. package/dist/client/assets/file-explorer-screen-CpY1O_ag.js +0 -1
  63. package/dist/client/assets/files-HiN5rXWq.js +0 -2
  64. package/dist/client/assets/keyboard-shortcuts-dialog-C2Hq19LN.js +0 -1
  65. package/dist/client/assets/memory-lhzf-8Q4.js +0 -2
  66. package/dist/client/assets/memory-screen-Zq9qfnJK.js +0 -1
  67. package/dist/client/assets/menu-47ooFeSm.js +0 -1
  68. package/dist/client/assets/owner-CFRNz_Tp.js +0 -1
  69. package/dist/client/assets/popupStateMapping-D5k-jOeY.js +0 -1
  70. package/dist/client/assets/search-dialog-C5Yae9rb.js +0 -1
  71. package/dist/client/assets/session-export-dialog-CBeTfbll.js +0 -1
  72. package/dist/client/assets/settings-dialog-CoeG9M1b.js +0 -1
  73. package/dist/client/assets/skills-BEkw619A.js +0 -2
  74. package/dist/client/assets/styles-D4EBtWYc.css +0 -1
  75. package/dist/client/assets/switch-DAFvLxNX.js +0 -1
  76. package/dist/client/assets/tabs-B2Y_7MvG.js +0 -1
  77. package/dist/client/assets/tooltip-D57Pal0B.js +0 -1
  78. package/dist/client/assets/use-file-explorer-state-DppKEjcl.js +0 -12
  79. package/dist/client/assets/useButton-DVAfkehQ.js +0 -1
  80. package/dist/client/assets/useCompositeItem-CzdGhGcj.js +0 -1
  81. package/dist/client/assets/visuallyHidden-CO3ZD5AQ.js +0 -1
  82. package/dist/server/assets/_tanstack-start-manifest_v-DmMFarHb.js +0 -4
  83. package/dist/server/assets/settings-dialog-D3fOAswX.js +0 -1173
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # OpenCami 🦎
2
2
 
3
- **Version 1.6.0**
3
+ **Version 1.7.0**
4
4
 
5
5
  A beautiful web client for [OpenClaw](https://github.com/openclaw/openclaw).
6
6
 
@@ -15,16 +15,28 @@ A beautiful web client for [OpenClaw](https://github.com/openclaw/openclaw).
15
15
  curl -fsSL https://opencami.xyz/install.sh | bash
16
16
  ```
17
17
 
18
- Or via npm:
18
+ Then open `http://localhost:3000` (or your configured host/port).
19
+
20
+ ---
21
+
22
+ ## Install (curl)
23
+
24
+ The recommended install flow is:
25
+
26
+ ```bash
27
+ curl -fsSL https://opencami.xyz/install.sh | bash
28
+ ```
29
+
30
+ This installs OpenCami and prints next-step instructions for required environment variables.
31
+
32
+ Alternative install:
19
33
 
20
34
  ```bash
21
35
  npm install -g opencami
22
36
  opencami
23
37
  ```
24
38
 
25
- Opens your browser to the chat interface.
26
-
27
- ### Options
39
+ CLI options:
28
40
 
29
41
  | Flag | Description | Default |
30
42
  |------|-------------|---------|
@@ -33,18 +45,166 @@ Opens your browser to the chat interface.
33
45
  | `--host` | Bind address | `localhost` |
34
46
  | `--no-open` | Don't open browser | — |
35
47
 
36
- ### Docker
48
+ > Note: `--gateway` sets `OPENCLAW_GATEWAY` internally. For predictable deployments, set `CLAWDBOT_GATEWAY_URL` explicitly in environment.
49
+
50
+ ---
51
+
52
+ ## Configuration (OpenCami environment)
53
+
54
+ Set these in your shell, service manager, or container environment.
55
+
56
+ ### Required
57
+
58
+ ```bash
59
+ CLAWDBOT_GATEWAY_URL=ws://127.0.0.1:18789
60
+ # pick ONE auth method:
61
+ CLAWDBOT_GATEWAY_TOKEN=...
62
+ # or
63
+ CLAWDBOT_GATEWAY_PASSWORD=...
64
+ ```
65
+
66
+ ### Required for remote Tailnet / origin allowlist setups
67
+
68
+ ```bash
69
+ # Must exactly match the browser origin used to access OpenCami
70
+ # Example: https://openclaw-server.tailXXXX.ts.net:3001
71
+ OPENCAMI_ORIGIN=https://openclaw-server.tailXXXX.ts.net:3001
72
+ ```
73
+
74
+ ### Optional
75
+
76
+ ```bash
77
+ # Enables compatibility fallback if strict device-auth connect fails
78
+ # Default is strict mode (fallback disabled)
79
+ OPENCAMI_DEVICE_AUTH_FALLBACK=true
80
+
81
+ FILES_ROOT=/path/to/workspace
82
+ OPENAI_API_KEY=sk-...
83
+ ```
84
+
85
+ ---
86
+
87
+ ## Remote Tailnet setup (OpenClaw + OpenCami)
88
+
89
+ If OpenCami loads remotely but you see **"origin not allowed"** or gateway connect failures, configure both sides.
90
+
91
+ ### 1) OpenClaw gateway config (`gateway.controlUi.allowedOrigins`)
92
+
93
+ In your OpenClaw config, allow the exact OpenCami browser origin:
94
+
95
+ ```json
96
+ {
97
+ "gateway": {
98
+ "controlUi": {
99
+ "allowedOrigins": [
100
+ "https://openclaw-server.tailXXXX.ts.net:3001"
101
+ ]
102
+ }
103
+ }
104
+ }
105
+ ```
106
+
107
+ ### 2) OpenCami server env (`OPENCAMI_ORIGIN`)
108
+
109
+ Set `OPENCAMI_ORIGIN` to the same exact value:
110
+
111
+ ```bash
112
+ OPENCAMI_ORIGIN=https://openclaw-server.tailXXXX.ts.net:3001
113
+ ```
114
+
115
+ ### 3) Restart gateway
116
+
117
+ ```bash
118
+ openclaw gateway restart
119
+ ```
120
+
121
+ > If you access OpenCami via multiple hostnames/ports, each distinct origin must be listed in `allowedOrigins`.
122
+
123
+ ---
124
+
125
+ ## Device auth notes (strict vs fallback)
126
+
127
+ OpenCami uses strict device-auth-compatible connect params by default.
128
+
129
+ - **Strict mode (default):** `OPENCAMI_DEVICE_AUTH_FALLBACK` unset/false
130
+ - **Fallback mode (compatibility):** set `OPENCAMI_DEVICE_AUTH_FALLBACK=true`
131
+
132
+ Fallback mode retries connect without device identity metadata if strict handshake fails.
133
+ Use fallback only when needed for compatibility, and prefer strict mode long-term.
134
+
135
+ ---
136
+
137
+ ## Security notes
138
+
139
+ - Prefer `wss://` for remote connections.
140
+ - Prefer token auth (`CLAWDBOT_GATEWAY_TOKEN`) over password.
141
+ - Keep `allowedOrigins` minimal (exact origins only, no wildcards).
142
+ - Treat `OPENCAMI_DEVICE_AUTH_FALLBACK=true` as temporary compatibility mode.
143
+ - Do **not** expose OpenCami directly to the public internet without TLS + access controls.
144
+ - For Tailnet deployments, limit Tailnet device/user access.
145
+
146
+ ---
147
+
148
+ ## Troubleshooting
149
+
150
+ ### "origin not allowed"
151
+
152
+ Cause: gateway rejected browser origin.
153
+
154
+ Fix:
155
+ 1. Add origin to `gateway.controlUi.allowedOrigins`
156
+ 2. Set identical `OPENCAMI_ORIGIN` in OpenCami env
157
+ 3. Restart gateway (`openclaw gateway restart`)
158
+
159
+ ### Missing scope `operator.read`
160
+
161
+ Cause: gateway auth succeeded but token/permissions did not include required operator scope.
162
+
163
+ Fix:
164
+ - Use a token/password with operator access
165
+ - Verify gateway auth/scopes in OpenClaw
166
+ - Reconnect after updating credentials
167
+
168
+ ### Pairing required / device auth connect issues
169
+
170
+ If strict connect fails in your deployment:
171
+
172
+ ```bash
173
+ OPENCAMI_DEVICE_AUTH_FALLBACK=true
174
+ ```
175
+
176
+ Then restart OpenCami and retry. Keep this as a compatibility fallback, not the default.
177
+
178
+ ### Can’t connect to gateway at all
179
+
180
+ Checks:
181
+
182
+ ```bash
183
+ openclaw gateway status
184
+ echo "$CLAWDBOT_GATEWAY_URL"
185
+ echo "$CLAWDBOT_GATEWAY_TOKEN"
186
+ ```
187
+
188
+ Also verify URL scheme (`ws://` local, `wss://` remote).
189
+
190
+ ---
191
+
192
+ ## Docker
37
193
 
38
194
  ```bash
39
195
  docker build -t opencami .
40
196
  docker run -p 3000:3000 opencami
41
197
  ```
42
198
 
199
+ ---
200
+
43
201
  ## Features
44
202
 
45
203
  ### 💬 Chat & Communication
46
204
  - ⚡ **Real-time streaming** — persistent WebSocket + SSE, token-by-token
47
- - 🖼️ **Image attachments** — drag & drop with compression
205
+ - 📎 **File attachments** — upload PDFs, text, code, CSV, JSON via attach button or drag & drop (`/uploads/` + `read` tool workflow)
206
+ - 📄 **File cards** — uploaded files render as clickable cards (filename, icon, size) and open in File Explorer
207
+ - 🖼️ **Image attachments** — drag & drop with compression (images stay Base64 for vision)
48
208
  - 🔊 **Voice playback (TTS)** — ElevenLabs → OpenAI → Edge TTS fallback
49
209
  - 🎤 **Voice input (STT)** — ElevenLabs Scribe → OpenAI Whisper → Browser
50
210
  - 🔔 **Browser notifications** — background tab alerts when assistant replies
package/bin/opencami.js CHANGED
@@ -18,6 +18,9 @@ function getArg(name, def) {
18
18
  const port = parseInt(getArg('port', '3000'), 10);
19
19
  const host = getArg('host', '127.0.0.1');
20
20
  const gateway = getArg('gateway', 'ws://127.0.0.1:18789');
21
+ const token = getArg('token', '');
22
+ const password = getArg('password', '');
23
+ const origin = getArg('origin', '');
21
24
  const noOpen = args.includes('--no-open');
22
25
 
23
26
  if (args.includes('--help') || args.includes('-h')) {
@@ -27,17 +30,23 @@ if (args.includes('--help') || args.includes('-h')) {
27
30
  Usage: opencami [options]
28
31
 
29
32
  Options:
30
- --port <n> Port to listen on (default: 3000)
31
- --host <addr> Host to bind to (default: 127.0.0.1)
32
- --gateway <url> OpenClaw gateway URL (default: ws://127.0.0.1:18789)
33
- --no-open Don't open browser on start
34
- -h, --help Show this help
33
+ --port <n> Port to listen on (default: 3000)
34
+ --host <addr> Host to bind to (default: 127.0.0.1)
35
+ --gateway <url> OpenClaw gateway URL (default: ws://127.0.0.1:18789)
36
+ --token <token> Gateway token (sets CLAWDBOT_GATEWAY_TOKEN)
37
+ --password <pw> Gateway password (sets CLAWDBOT_GATEWAY_PASSWORD)
38
+ --origin <url> Origin to send in backend WS (sets OPENCAMI_ORIGIN)
39
+ --no-open Don't open browser on start
40
+ -h, --help Show this help
35
41
  `);
36
42
  process.exit(0);
37
43
  }
38
44
 
39
45
  // Set gateway env for the app
40
- process.env.OPENCLAW_GATEWAY = gateway;
46
+ process.env.CLAWDBOT_GATEWAY_URL = gateway;
47
+ if (token) process.env.CLAWDBOT_GATEWAY_TOKEN = token;
48
+ if (password) process.env.CLAWDBOT_GATEWAY_PASSWORD = password;
49
+ if (origin) process.env.OPENCAMI_ORIGIN = origin;
41
50
 
42
51
  const MIME_TYPES = {
43
52
  '.html': 'text/html',
@@ -1 +1 @@
1
- import{r as t}from"./main-CEuT8-Qi.js";const e=t.createContext(void 0),o={disableStyleElements:!1};function s(){return t.useContext(e)??o}export{s as u};
1
+ import{r as t}from"./main-CgwdHc9W.js";const e=t.createContext(void 0),o={disableStyleElements:!1};function s(){return t.useContext(e)??o}export{s as u};
@@ -1 +1 @@
1
- import{r as l}from"./main-CEuT8-Qi.js";const E=["top","right","bottom","left"],p=Math.min,h=Math.max,L=Math.round,k=Math.floor,q=t=>({x:t,y:t}),x={left:"right",right:"left",bottom:"top",top:"bottom"},d={start:"end",end:"start"};function R(t,e,n){return h(t,p(e,n))}function T(t,e){return typeof t=="function"?t(e):t}function m(t){return t.split("-")[0]}function g(t){return t.split("-")[1]}function b(t){return t==="x"?"y":"x"}function A(t){return t==="y"?"height":"width"}const P=new Set(["top","bottom"]);function y(t){return P.has(m(t))?"y":"x"}function M(t){return b(y(t))}function v(t,e,n){n===void 0&&(n=!1);const s=g(t),i=M(t),o=A(i);let r=i==="x"?s===(n?"end":"start")?"right":"left":s==="start"?"bottom":"top";return e.reference[o]>e.floating[o]&&(r=a(r)),[r,a(r)]}function z(t){const e=a(t);return[c(t),e,c(e)]}function c(t){return t.replace(/start|end/g,e=>d[e])}const u=["left","right"],f=["right","left"],O=["top","bottom"],S=["bottom","top"];function C(t,e,n){switch(t){case"top":case"bottom":return n?e?f:u:e?u:f;case"left":case"right":return e?O:S;default:return[]}}function B(t,e,n,s){const i=g(t);let o=C(m(t),n==="start",s);return i&&(o=o.map(r=>r+"-"+i),e&&(o=o.concat(o.map(c)))),o}function a(t){return t.replace(/left|right|bottom|top/g,e=>x[e])}function w(t){return{top:0,right:0,bottom:0,left:0,...t}}function F(t){return typeof t!="number"?w(t):{top:t,right:t,bottom:t,left:t}}function G(t){const{x:e,y:n,width:s,height:i}=t;return{width:s,height:i,top:n,left:e,right:e+s,bottom:n+i,x:e,y:n}}const j=l.createContext(void 0);function H(){return l.useContext(j)?.direction??"ltr"}export{y as a,a as b,z as c,B as d,T as e,k as f,m as g,v as h,g as i,h as j,M as k,F as l,p as m,G as n,A as o,R as p,b as q,L as r,E as s,q as t,H as u};
1
+ import{r as l}from"./main-CgwdHc9W.js";const E=["top","right","bottom","left"],p=Math.min,h=Math.max,L=Math.round,k=Math.floor,q=t=>({x:t,y:t}),x={left:"right",right:"left",bottom:"top",top:"bottom"},d={start:"end",end:"start"};function R(t,e,n){return h(t,p(e,n))}function T(t,e){return typeof t=="function"?t(e):t}function m(t){return t.split("-")[0]}function g(t){return t.split("-")[1]}function b(t){return t==="x"?"y":"x"}function A(t){return t==="y"?"height":"width"}const P=new Set(["top","bottom"]);function y(t){return P.has(m(t))?"y":"x"}function M(t){return b(y(t))}function v(t,e,n){n===void 0&&(n=!1);const s=g(t),i=M(t),o=A(i);let r=i==="x"?s===(n?"end":"start")?"right":"left":s==="start"?"bottom":"top";return e.reference[o]>e.floating[o]&&(r=a(r)),[r,a(r)]}function z(t){const e=a(t);return[c(t),e,c(e)]}function c(t){return t.replace(/start|end/g,e=>d[e])}const u=["left","right"],f=["right","left"],O=["top","bottom"],S=["bottom","top"];function C(t,e,n){switch(t){case"top":case"bottom":return n?e?f:u:e?u:f;case"left":case"right":return e?O:S;default:return[]}}function B(t,e,n,s){const i=g(t);let o=C(m(t),n==="start",s);return i&&(o=o.map(r=>r+"-"+i),e&&(o=o.concat(o.map(c)))),o}function a(t){return t.replace(/left|right|bottom|top/g,e=>x[e])}function w(t){return{top:0,right:0,bottom:0,left:0,...t}}function F(t){return typeof t!="number"?w(t):{top:t,right:t,bottom:t,left:t}}function G(t){const{x:e,y:n,width:s,height:i}=t;return{width:s,height:i,top:n,left:e,right:e+s,bottom:n+i,x:e,y:n}}const j=l.createContext(void 0);function H(){return l.useContext(j)?.direction??"ltr"}export{y as a,a as b,z as c,B as d,T as e,k as f,m as g,v as h,g as i,h as j,M as k,F as l,p as m,G as n,A as o,R as p,b as q,L as r,E as s,q as t,H as u};