opencami 1.5.0 → 1.6.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 (118) hide show
  1. package/README.md +4 -1
  2. package/dist/client/assets/{CSPContext-EgWK8bIJ.js → CSPContext-Bq8j4nl9.js} +1 -1
  3. package/dist/client/assets/DirectionContext-BdX86BHP.js +1 -0
  4. package/dist/client/assets/_sessionKey-DsjnpErt.js +14 -0
  5. package/dist/client/assets/agents-DwxKcpP6.js +2 -0
  6. package/dist/client/assets/agents-screen-DwIY8hze.js +1 -0
  7. package/dist/client/assets/bots-CRlm-3-d.js +2 -0
  8. package/dist/client/assets/bots-screen-c78I920d.js +1 -0
  9. package/dist/client/assets/button-Dg7VFQQn.js +1 -0
  10. package/dist/client/assets/c-BIGW1oBm.js +1 -0
  11. package/dist/client/assets/composite-DBl8R3ae.js +1 -0
  12. package/dist/client/assets/{connect-w4lLOqiJ.js → connect-NYvOqiBJ.js} +1 -1
  13. package/dist/client/assets/core-BrHBc0Zp.js +12 -0
  14. package/dist/client/assets/cpp-B-lmv-kZ.js +1 -0
  15. package/dist/client/assets/csharp-K5feNrxe.js +1 -0
  16. package/dist/client/assets/css-DPfMkruS.js +1 -0
  17. package/dist/client/assets/diff-D97Zzqfu.js +1 -0
  18. package/dist/client/assets/dockerfile-BcOcwvcX.js +1 -0
  19. package/dist/client/assets/engine-javascript-PwbX1GN8.js +141 -0
  20. package/dist/client/assets/file-explorer-screen-BSMbs0vi.js +1 -0
  21. package/dist/client/assets/files-BJbMx0_w.js +2 -0
  22. package/dist/client/assets/go-Dn2_MT6a.js +1 -0
  23. package/dist/client/assets/graphql-ChdNCCLP.js +1 -0
  24. package/dist/client/assets/html-GMplVEZG.js +1 -0
  25. package/dist/client/assets/index-CMATW8VA.js +3 -0
  26. package/dist/client/assets/index-T4TOjvD0.js +1 -0
  27. package/dist/client/assets/{index-36G0WCxU.js → index-rOIRO-8E.js} +1 -1
  28. package/dist/client/assets/java-CylS5w8V.js +1 -0
  29. package/dist/client/assets/javascript-wDzz0qaB.js +1 -0
  30. package/dist/client/assets/json-Cp-IABpG.js +1 -0
  31. package/dist/client/assets/jsx-g9-lgVsj.js +1 -0
  32. package/dist/client/assets/keyboard-shortcuts-dialog-BTGWdJMl.js +1 -0
  33. package/dist/client/assets/kotlin-BdnUsdx6.js +1 -0
  34. package/dist/client/assets/{main-B3N0eQFg.js → main-B_dlfHME.js} +9 -9
  35. package/dist/client/assets/markdown-BVzT7z4x.js +87 -0
  36. package/dist/client/assets/markdown-Cvjx9yec.js +1 -0
  37. package/dist/client/assets/memory-S3Yws6a5.js +2 -0
  38. package/dist/client/assets/memory-screen-C-Z9o31m.js +1 -0
  39. package/dist/client/assets/menu-DHNgWk_8.js +1 -0
  40. package/dist/client/assets/{opencami-logo-DD0DPFRQ.js → opencami-logo-BQQETnJG.js} +1 -1
  41. package/dist/client/assets/owner-CpRnf1fI.js +1 -0
  42. package/dist/client/assets/php-CDn_0X-4.js +1 -0
  43. package/dist/client/assets/popupStateMapping-BRPDXnjv.js +1 -0
  44. package/dist/client/assets/proxy-BcUh9kMA.js +9 -0
  45. package/dist/client/assets/python-B6aJPvgy.js +1 -0
  46. package/dist/client/assets/react-irH8OzhB.js +1 -0
  47. package/dist/client/assets/regexp-CDVJQ6XC.js +1 -0
  48. package/dist/client/assets/ruby-FDmvQDUv.js +1 -0
  49. package/dist/client/assets/rust-B1yitclQ.js +1 -0
  50. package/dist/client/assets/search-dialog-B96zx_ng.js +1 -0
  51. package/dist/client/assets/session-export-dialog-DPuHnhgv.js +1 -0
  52. package/dist/client/assets/settings-dialog-DZcRCaPj.js +1 -0
  53. package/dist/client/assets/shell-DfDnw5Jg.js +1 -0
  54. package/dist/client/assets/skills-YZe3I63y.js +2 -0
  55. package/dist/client/assets/{skills-panel-BLUjzfjJ.js → skills-panel-WDUfIwnI.js} +2 -2
  56. package/dist/client/assets/sql-BLtJtn59.js +1 -0
  57. package/dist/client/assets/styles-Bwo-K6Y4.css +1 -0
  58. package/dist/client/assets/swift-Dg5xB15N.js +1 -0
  59. package/dist/client/assets/switch-DPocNFRG.js +1 -0
  60. package/dist/client/assets/tabs-B0cro1hL.js +1 -0
  61. package/dist/client/assets/toml-vGWfd6FD.js +1 -0
  62. package/dist/client/assets/tooltip-Dg9fy-vT.js +1 -0
  63. package/dist/client/assets/tsx-COt5Ahok.js +1 -0
  64. package/dist/client/assets/typescript-BPQ3VLAy.js +1 -0
  65. package/dist/client/assets/use-file-explorer-state-DzT0bksg.js +12 -0
  66. package/dist/client/assets/useButton-Cbl_9oFG.js +1 -0
  67. package/dist/client/assets/useCompositeItem-BDAzTxVe.js +1 -0
  68. package/dist/client/assets/{useControlled-BhUuiHAm.js → useControlled-Dscz_s4f.js} +1 -1
  69. package/dist/client/assets/{useMutation-CFmVaBag.js → useMutation-B1FlDsNN.js} +1 -1
  70. package/dist/client/assets/visuallyHidden-ONmQ-0U2.js +1 -0
  71. package/dist/client/assets/vitesse-dark-D0r3Knsf.js +1 -0
  72. package/dist/client/assets/vitesse-light-CVO1_9PV.js +1 -0
  73. package/dist/client/assets/xml-sdJ4AIDG.js +1 -0
  74. package/dist/client/assets/yaml-Buea-lGh.js +1 -0
  75. package/dist/server/assets/{_sessionKey-tRze5NLR.js → _sessionKey-B0ZlLAjH.js} +184 -575
  76. package/dist/server/assets/_tanstack-start-manifest_v-D5UVTs1o.js +4 -0
  77. package/dist/server/assets/{connect-d3AqjAqe.js → connect-CbgijWz4.js} +1 -34
  78. package/dist/server/assets/{file-explorer-screen-CVlFiAFu.js → file-explorer-screen-DH4UFK03.js} +3 -2
  79. package/dist/server/assets/{files-BIEcSPGp.js → files-DYdXlQDr.js} +1 -1
  80. package/dist/server/assets/{index-CRfLKh30.js → index-CiUjUD0t.js} +1 -1
  81. package/dist/server/assets/{index-CNIATlJ9.js → index-Dl2BOKP7.js} +94 -79
  82. package/dist/server/assets/{keyboard-shortcuts-dialog-CsNP85q8.js → keyboard-shortcuts-dialog-Cr6fOqHz.js} +1 -2
  83. package/dist/server/assets/markdown-BFE5y9YH.js +565 -0
  84. package/dist/server/assets/memory-BqZOoD7Q.js +11 -0
  85. package/dist/server/assets/memory-screen-BK5phS8K.js +235 -0
  86. package/dist/server/assets/menu-D90CDTi2.js +45 -0
  87. package/dist/server/assets/{router-rn7pJO_D.js → router-Uuagl6O7.js} +56 -46
  88. package/dist/server/assets/{search-dialog-Bz4Cu0KW.js → search-dialog-DZTS5SEi.js} +49 -83
  89. package/dist/server/assets/{session-export-dialog-CwclV0Aj.js → session-export-dialog-C53RRAah.js} +1 -2
  90. package/dist/server/assets/{settings-dialog-BBM7jCjE.js → settings-dialog-CSYDj2qm.js} +82 -56
  91. package/dist/server/assets/{use-file-explorer-state-Il1LlBAe.js → use-file-explorer-state-s7CS50ho.js} +0 -41
  92. package/dist/server/server.js +2 -2
  93. package/package.json +2 -1
  94. package/dist/client/assets/DirectionContext-DXtY05YF.js +0 -1
  95. package/dist/client/assets/_sessionKey-B89e7G3y.js +0 -100
  96. package/dist/client/assets/agents-screen-1BiEZ9od.js +0 -1
  97. package/dist/client/assets/agents-x54ocA9z.js +0 -2
  98. package/dist/client/assets/bots-screen-BNQciUeJ.js +0 -1
  99. package/dist/client/assets/bots-x86ZHG4b.js +0 -2
  100. package/dist/client/assets/button-nDcsaNPl.js +0 -1
  101. package/dist/client/assets/file-explorer-screen-CAsjd3w8.js +0 -1
  102. package/dist/client/assets/files-Bype5Mnb.js +0 -2
  103. package/dist/client/assets/index-BXkRE220.js +0 -153
  104. package/dist/client/assets/keyboard-shortcuts-dialog-BdCeXRjD.js +0 -1
  105. package/dist/client/assets/react-B16OrBeM.js +0 -1
  106. package/dist/client/assets/search-dialog-BjTPceEl.js +0 -1
  107. package/dist/client/assets/session-export-dialog-DtHKG2zW.js +0 -1
  108. package/dist/client/assets/settings-dialog-hiqdk_UD.js +0 -1
  109. package/dist/client/assets/skills-DhwyFq3y.js +0 -2
  110. package/dist/client/assets/styles-CHP4l6vZ.css +0 -1
  111. package/dist/client/assets/switch-J6wLIVu2.js +0 -1
  112. package/dist/client/assets/tabs-DvPgTz5I.js +0 -1
  113. package/dist/client/assets/tooltip-C14vdXHK.js +0 -1
  114. package/dist/client/assets/use-file-explorer-state-BnaJEqRP.js +0 -12
  115. package/dist/client/assets/useButton-Bnnac1eR.js +0 -1
  116. package/dist/client/assets/useCompositeItem-BgiEMKAt.js +0 -1
  117. package/dist/client/assets/visuallyHidden-DCCICp6T.js +0 -9
  118. package/dist/server/assets/_tanstack-start-manifest_v-CyfoMvUa.js +0 -4
@@ -3,12 +3,11 @@ import { useState, useRef, useEffect, useCallback, useMemo } from "react";
3
3
  import { useNavigate } from "@tanstack/react-router";
4
4
  import { HugeiconsIcon } from "@hugeicons/react";
5
5
  import { Search01Icon, Cancel01Icon, Loading03Icon } from "@hugeicons/core-free-icons";
6
- import { D as DialogRoot, a as DialogContent } from "./use-file-explorer-state-Il1LlBAe.js";
6
+ import { D as DialogRoot, a as DialogContent } from "./use-file-explorer-state-s7CS50ho.js";
7
7
  import { useQueryClient } from "@tanstack/react-query";
8
- import { c as chatQueryKeys } from "./_sessionKey-tRze5NLR.js";
8
+ import { c as chatQueryKeys } from "./_sessionKey-B0ZlLAjH.js";
9
9
  import { c as cn } from "./button-CwY2OHFj.js";
10
10
  import "@base-ui/react/dialog";
11
- import "@base-ui/react/menu";
12
11
  import "zustand";
13
12
  import "./tooltip-DgsSPocE.js";
14
13
  import "@base-ui/react/tooltip";
@@ -16,48 +15,18 @@ import "motion/react";
16
15
  import "@base-ui/react/alert-dialog";
17
16
  import "@base-ui/react/collapsible";
18
17
  import "@base-ui/react/scroll-area";
18
+ import "./menu-D90CDTi2.js";
19
+ import "@base-ui/react/menu";
19
20
  import "./opencami-logo-C-43FL3R.js";
21
+ import "./markdown-BFE5y9YH.js";
20
22
  import "marked";
21
23
  import "react-markdown";
22
24
  import "remark-breaks";
23
25
  import "remark-gfm";
24
- import "./index-CNIATlJ9.js";
25
- import "shiki/core";
26
- import "shiki/engine/javascript";
27
- import "@shikijs/themes/vitesse-dark";
28
- import "@shikijs/themes/vitesse-light";
29
- import "@shikijs/langs/bash";
30
- import "@shikijs/langs/c";
31
- import "@shikijs/langs/cpp";
32
- import "@shikijs/langs/csharp";
33
- import "@shikijs/langs/css";
34
- import "@shikijs/langs/diff";
35
- import "@shikijs/langs/dockerfile";
36
- import "@shikijs/langs/go";
37
- import "@shikijs/langs/graphql";
38
- import "@shikijs/langs/html";
39
- import "@shikijs/langs/java";
40
- import "@shikijs/langs/javascript";
41
- import "@shikijs/langs/json";
42
- import "@shikijs/langs/jsx";
43
- import "@shikijs/langs/kotlin";
44
- import "@shikijs/langs/markdown";
45
- import "@shikijs/langs/php";
46
- import "@shikijs/langs/python";
47
- import "@shikijs/langs/regexp";
48
- import "@shikijs/langs/ruby";
49
- import "@shikijs/langs/rust";
50
- import "@shikijs/langs/shell";
51
- import "@shikijs/langs/sql";
52
- import "@shikijs/langs/swift";
53
- import "@shikijs/langs/toml";
54
- import "@shikijs/langs/typescript";
55
- import "@shikijs/langs/tsx";
56
- import "@shikijs/langs/xml";
57
- import "@shikijs/langs/yaml";
26
+ import "./index-Dl2BOKP7.js";
58
27
  import "zustand/middleware";
59
28
  import "react-dom";
60
- import "./router-rn7pJO_D.js";
29
+ import "./router-Uuagl6O7.js";
61
30
  import "node:crypto";
62
31
  import "ws";
63
32
  import "node:fs";
@@ -160,58 +129,55 @@ function useSearch({ sessions, currentFriendlyId, currentSessionKey }) {
160
129
  throw new DOMException("Search aborted", "AbortError");
161
130
  }
162
131
  const batch = sessions.slice(i, i + BATCH_SIZE);
163
- const batchResults = await Promise.all(
132
+ const batchSettled = await Promise.allSettled(
164
133
  batch.map(async (session) => {
165
- try {
166
- const historyKey = chatQueryKeys.history(session.friendlyId, session.key);
167
- let historyData = queryClient.getQueryData(historyKey);
168
- if (!historyData) {
169
- const params = new URLSearchParams({
134
+ const historyKey = chatQueryKeys.history(session.friendlyId, session.key);
135
+ let historyData = queryClient.getQueryData(historyKey);
136
+ if (!historyData) {
137
+ const params = new URLSearchParams({
138
+ sessionKey: session.key,
139
+ friendlyId: session.friendlyId,
140
+ limit: "200"
141
+ });
142
+ const res = await fetch(`/api/history?${params.toString()}`, {
143
+ signal: controller.signal
144
+ });
145
+ if (res.ok) {
146
+ historyData = await res.json();
147
+ queryClient.setQueryData(historyKey, historyData);
148
+ }
149
+ }
150
+ if (!historyData?.messages) return [];
151
+ const sessionTitle = session.label || session.title || session.derivedTitle || session.friendlyId;
152
+ const sessionResults = [];
153
+ historyData.messages.forEach((message, index) => {
154
+ const text = extractTextFromMessage(message);
155
+ if (!text) return;
156
+ const lowerText = text.toLowerCase();
157
+ const matchIndex = lowerText.indexOf(normalizedQuery);
158
+ if (matchIndex !== -1) {
159
+ sessionResults.push({
170
160
  sessionKey: session.key,
171
161
  friendlyId: session.friendlyId,
172
- limit: "200"
162
+ sessionTitle,
163
+ messageIndex: index,
164
+ messageId: typeof message.id === "string" ? message.id : void 0,
165
+ messageRole: message.role || "unknown",
166
+ messageText: text,
167
+ matchStart: matchIndex,
168
+ matchEnd: matchIndex + trimmedQuery.length,
169
+ timestamp: message.timestamp
173
170
  });
174
- const res = await fetch(`/api/history?${params.toString()}`, {
175
- signal: controller.signal
176
- });
177
- if (res.ok) {
178
- historyData = await res.json();
179
- queryClient.setQueryData(historyKey, historyData);
180
- }
181
- }
182
- if (!historyData?.messages) return [];
183
- const sessionTitle = session.label || session.title || session.derivedTitle || session.friendlyId;
184
- const sessionResults = [];
185
- historyData.messages.forEach((message, index) => {
186
- const text = extractTextFromMessage(message);
187
- if (!text) return;
188
- const lowerText = text.toLowerCase();
189
- const matchIndex = lowerText.indexOf(normalizedQuery);
190
- if (matchIndex !== -1) {
191
- sessionResults.push({
192
- sessionKey: session.key,
193
- friendlyId: session.friendlyId,
194
- sessionTitle,
195
- messageIndex: index,
196
- messageId: typeof message.id === "string" ? message.id : void 0,
197
- messageRole: message.role || "unknown",
198
- messageText: text,
199
- matchStart: matchIndex,
200
- matchEnd: matchIndex + trimmedQuery.length,
201
- timestamp: message.timestamp
202
- });
203
- }
204
- });
205
- return sessionResults;
206
- } catch (error) {
207
- if (error instanceof DOMException && error.name === "AbortError") {
208
- throw error;
209
171
  }
210
- return [];
211
- }
172
+ });
173
+ return sessionResults;
212
174
  })
213
175
  );
214
- allResults.push(...batchResults.flat());
176
+ for (const result of batchSettled) {
177
+ if (result.status === "fulfilled") {
178
+ allResults.push(...result.value);
179
+ }
180
+ }
215
181
  allResults.sort((a, b) => (b.timestamp || 0) - (a.timestamp || 0));
216
182
  setGlobalResults([...allResults]);
217
183
  }
@@ -1,9 +1,8 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useState } from "react";
3
- import { D as DialogRoot, a as DialogContent, b as DialogTitle, c as DialogDescription, d as DialogClose } from "./use-file-explorer-state-Il1LlBAe.js";
3
+ import { D as DialogRoot, a as DialogContent, b as DialogTitle, c as DialogDescription, d as DialogClose } from "./use-file-explorer-state-s7CS50ho.js";
4
4
  import { B as Button } from "./button-CwY2OHFj.js";
5
5
  import "@base-ui/react/dialog";
6
- import "@base-ui/react/menu";
7
6
  import "zustand";
8
7
  import "@base-ui/react/merge-props";
9
8
  import "@base-ui/react/use-render";
@@ -2,55 +2,21 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useState, useEffect, useRef } from "react";
3
3
  import { B as Button, c as cn } from "./button-CwY2OHFj.js";
4
4
  import { HugeiconsIcon } from "@hugeicons/react";
5
- import { Cancel01Icon, Link01Icon, PaintBoardIcon, MessageEdit01Icon, UserIcon, VoiceIcon, AiBrain01Icon, InformationCircleIcon, ComputerIcon, Sun01Icon, Moon01Icon, Leaf01Icon, DropletIcon, Loading02Icon, Tick01Icon, Cancel02Icon } from "@hugeicons/core-free-icons";
6
- import { D as DialogRoot, a as DialogContent, b as DialogTitle, c as DialogDescription, d as DialogClose } from "./use-file-explorer-state-Il1LlBAe.js";
5
+ import { Cancel01Icon, Link01Icon, PaintBoardIcon, MessageEdit01Icon, Settings02Icon, UserIcon, VoiceIcon, AiBrain01Icon, InformationCircleIcon, ComputerIcon, Sun01Icon, Moon01Icon, Leaf01Icon, DropletIcon, Loading02Icon, Tick01Icon, Cancel02Icon } from "@hugeicons/core-free-icons";
6
+ import { D as DialogRoot, a as DialogContent, b as DialogTitle, c as DialogDescription, d as DialogClose } from "./use-file-explorer-state-s7CS50ho.js";
7
7
  import { S as Switch } from "./switch-BbkUeVDV.js";
8
8
  import { T as Tabs, a as TabsList, b as TabsTab } from "./tabs-DDFZob0m.js";
9
- import { u as useChatSettings } from "./index-CNIATlJ9.js";
10
- import { u as useLlmSettings, g as getLlmProviderDefaults } from "./_sessionKey-tRze5NLR.js";
9
+ import { u as useChatSettings } from "./index-Dl2BOKP7.js";
10
+ import { u as useLlmSettings, g as getLlmProviderDefaults } from "./_sessionKey-B0ZlLAjH.js";
11
11
  import "@base-ui/react/merge-props";
12
12
  import "@base-ui/react/use-render";
13
13
  import "class-variance-authority";
14
14
  import "clsx";
15
15
  import "tailwind-merge";
16
16
  import "@base-ui/react/dialog";
17
- import "@base-ui/react/menu";
18
17
  import "zustand";
19
18
  import "@base-ui/react/switch";
20
19
  import "@base-ui/react/tabs";
21
- import "shiki/core";
22
- import "shiki/engine/javascript";
23
- import "@shikijs/themes/vitesse-dark";
24
- import "@shikijs/themes/vitesse-light";
25
- import "@shikijs/langs/bash";
26
- import "@shikijs/langs/c";
27
- import "@shikijs/langs/cpp";
28
- import "@shikijs/langs/csharp";
29
- import "@shikijs/langs/css";
30
- import "@shikijs/langs/diff";
31
- import "@shikijs/langs/dockerfile";
32
- import "@shikijs/langs/go";
33
- import "@shikijs/langs/graphql";
34
- import "@shikijs/langs/html";
35
- import "@shikijs/langs/java";
36
- import "@shikijs/langs/javascript";
37
- import "@shikijs/langs/json";
38
- import "@shikijs/langs/jsx";
39
- import "@shikijs/langs/kotlin";
40
- import "@shikijs/langs/markdown";
41
- import "@shikijs/langs/php";
42
- import "@shikijs/langs/python";
43
- import "@shikijs/langs/regexp";
44
- import "@shikijs/langs/ruby";
45
- import "@shikijs/langs/rust";
46
- import "@shikijs/langs/shell";
47
- import "@shikijs/langs/sql";
48
- import "@shikijs/langs/swift";
49
- import "@shikijs/langs/toml";
50
- import "@shikijs/langs/typescript";
51
- import "@shikijs/langs/tsx";
52
- import "@shikijs/langs/xml";
53
- import "@shikijs/langs/yaml";
54
20
  import "zustand/middleware";
55
21
  import "@tanstack/react-router";
56
22
  import "@tanstack/react-query";
@@ -60,13 +26,16 @@ import "motion/react";
60
26
  import "@base-ui/react/alert-dialog";
61
27
  import "@base-ui/react/collapsible";
62
28
  import "@base-ui/react/scroll-area";
29
+ import "./menu-D90CDTi2.js";
30
+ import "@base-ui/react/menu";
63
31
  import "./opencami-logo-C-43FL3R.js";
32
+ import "./markdown-BFE5y9YH.js";
64
33
  import "marked";
65
34
  import "react-markdown";
66
35
  import "remark-breaks";
67
36
  import "remark-gfm";
68
37
  import "react-dom";
69
- import "./router-rn7pJO_D.js";
38
+ import "./router-Uuagl6O7.js";
70
39
  import "node:crypto";
71
40
  import "ws";
72
41
  import "node:fs";
@@ -545,8 +514,7 @@ function SettingsDialog({
545
514
  { value: "light", label: "Light", icon: Sun01Icon },
546
515
  { value: "dark", label: "Dark", icon: Moon01Icon },
547
516
  { value: "chameleon", label: "Cham", icon: Leaf01Icon },
548
- { value: "frost-light", label: "Ice", icon: DropletIcon },
549
- { value: "frost-dark", label: "Noir", icon: DropletIcon }
517
+ { value: "frost-light", label: "Ice", icon: DropletIcon }
550
518
  ];
551
519
  function applyTheme(theme) {
552
520
  if (typeof document === "undefined") return;
@@ -598,6 +566,7 @@ function SettingsDialog({
598
566
  { id: "connection", label: "Connection", icon: Link01Icon },
599
567
  { id: "appearance", label: "Appearance", icon: PaintBoardIcon },
600
568
  { id: "chat", label: "Chat", icon: MessageEdit01Icon },
569
+ { id: "workspace", label: "Workspace", icon: Settings02Icon },
601
570
  { id: "personas", label: "Personas", icon: UserIcon },
602
571
  { id: "voice", label: "Voice", icon: VoiceIcon },
603
572
  { id: "llm", label: "LLM Features", icon: AiBrain01Icon },
@@ -729,6 +698,73 @@ function SettingsDialog({
729
698
  onCheckedChange: (checked) => updateSettings({ showSearchSources: checked })
730
699
  }
731
700
  ) }),
701
+ /* @__PURE__ */ jsx(
702
+ SettingsRow,
703
+ {
704
+ inline: true,
705
+ label: "Inline File Preview",
706
+ description: "Make file paths in messages clickable to preview file contents",
707
+ children: /* @__PURE__ */ jsx(
708
+ Switch,
709
+ {
710
+ checked: settings.inlineFilePreview,
711
+ onCheckedChange: (checked) => updateSettings({ inlineFilePreview: checked })
712
+ }
713
+ )
714
+ }
715
+ )
716
+ ] }),
717
+ /* @__PURE__ */ jsxs(SettingsSection, { title: "Workspace", tabId: "workspace", activeTab, children: [
718
+ /* @__PURE__ */ jsx(
719
+ SettingsRow,
720
+ {
721
+ inline: true,
722
+ label: "File Explorer",
723
+ description: "Browse and edit workspace files from the sidebar",
724
+ children: /* @__PURE__ */ jsx(
725
+ Switch,
726
+ {
727
+ checked: (() => {
728
+ try {
729
+ const v = localStorage.getItem("opencami-file-explorer");
730
+ return v === null ? true : v === "true";
731
+ } catch {
732
+ return true;
733
+ }
734
+ })(),
735
+ onCheckedChange: (checked) => {
736
+ localStorage.setItem("opencami-file-explorer", String(checked));
737
+ window.location.reload();
738
+ }
739
+ }
740
+ )
741
+ }
742
+ ),
743
+ /* @__PURE__ */ jsx(
744
+ SettingsRow,
745
+ {
746
+ inline: true,
747
+ label: "Memory Viewer",
748
+ description: "Browse and edit MEMORY.md and daily memory files",
749
+ children: /* @__PURE__ */ jsx(
750
+ Switch,
751
+ {
752
+ checked: (() => {
753
+ try {
754
+ const v = localStorage.getItem("opencami-memory-viewer");
755
+ return v === null ? true : v === "true";
756
+ } catch {
757
+ return true;
758
+ }
759
+ })(),
760
+ onCheckedChange: (checked) => {
761
+ localStorage.setItem("opencami-memory-viewer", String(checked));
762
+ window.location.reload();
763
+ }
764
+ }
765
+ )
766
+ }
767
+ ),
732
768
  /* @__PURE__ */ jsx(
733
769
  SettingsRow,
734
770
  {
@@ -800,21 +836,6 @@ function SettingsDialog({
800
836
  }
801
837
  )
802
838
  }
803
- ),
804
- /* @__PURE__ */ jsx(
805
- SettingsRow,
806
- {
807
- inline: true,
808
- label: "Inline File Preview",
809
- description: "Make file paths in messages clickable to preview file contents",
810
- children: /* @__PURE__ */ jsx(
811
- Switch,
812
- {
813
- checked: settings.inlineFilePreview,
814
- onCheckedChange: (checked) => updateSettings({ inlineFilePreview: checked })
815
- }
816
- )
817
- }
818
839
  )
819
840
  ] }),
820
841
  /* @__PURE__ */ jsxs(SettingsSection, { title: "Personas", tabId: "personas", activeTab, children: [
@@ -1028,6 +1049,11 @@ function SettingsDialog({
1028
1049
  /* @__PURE__ */ jsxs("div", { className: "mt-4 pt-3 border-t border-primary-100", children: [
1029
1050
  /* @__PURE__ */ jsx("div", { className: "text-sm text-primary-800 mb-2", children: llmSettings.llmProvider === "ollama" ? "API Key (optional)" : "API Key" }),
1030
1051
  /* @__PURE__ */ jsx("div", { className: "text-xs text-primary-500 mb-2", children: llmSettings.llmProvider === "ollama" ? "Not required for local Ollama" : llmStatus.hasEnvKey && llmSettings.llmProvider === "openai" ? "Optional: Override server key with your own" : `Required for ${llmSettings.llmProvider === "openrouter" ? "OpenRouter" : "LLM features"} (stored locally)` }),
1052
+ /* @__PURE__ */ jsxs("div", { className: "text-xs text-amber-600 bg-amber-50 border border-amber-200 rounded-md px-2 py-1.5 mb-2", children: [
1053
+ "⚠️ ",
1054
+ /* @__PURE__ */ jsx("strong", { children: "Security Note:" }),
1055
+ " API keys are stored in your browser's localStorage. This is convenient but not secure for shared computers. For production use, configure keys server-side via environment variables (OPENAI_API_KEY, OPENROUTER_API_KEY)."
1056
+ ] }),
1031
1057
  /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
1032
1058
  /* @__PURE__ */ jsx(
1033
1059
  "input",
@@ -1,7 +1,6 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Dialog } from "@base-ui/react/dialog";
3
3
  import { c as cn, B as Button } from "./button-CwY2OHFj.js";
4
- import { Menu } from "@base-ui/react/menu";
5
4
  import { create } from "zustand";
6
5
  function DialogRoot({ children, ...props }) {
7
6
  return /* @__PURE__ */ jsx(Dialog.Root, { ...props, children });
@@ -52,42 +51,6 @@ function DialogClose({ className, render, ...props }) {
52
51
  }
53
52
  );
54
53
  }
55
- function MenuRoot({ children, ...props }) {
56
- return /* @__PURE__ */ jsx(Menu.Root, { ...props, children });
57
- }
58
- function MenuTrigger({ className, ...props }) {
59
- return /* @__PURE__ */ jsx(Menu.Trigger, { className: cn(className), ...props });
60
- }
61
- function MenuContent({
62
- className,
63
- side = "bottom",
64
- align = "end",
65
- children
66
- }) {
67
- return /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, { side, align, children: /* @__PURE__ */ jsx(
68
- Menu.Popup,
69
- {
70
- className: cn(
71
- "min-w-[110px] rounded-lg bg-primary-50 p-1 text-sm text-primary-900 shadow-lg outline outline-primary-900/10",
72
- className
73
- ),
74
- children
75
- }
76
- ) }) });
77
- }
78
- function MenuItem({ className, ...props }) {
79
- return /* @__PURE__ */ jsx(
80
- Menu.Item,
81
- {
82
- className: cn(
83
- "flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm text-primary-900 hover:bg-primary-100 data-highlighted:bg-primary-100",
84
- "select-none font-[450]",
85
- className
86
- ),
87
- ...props
88
- }
89
- );
90
- }
91
54
  const useFileExplorerState = create((set, get) => ({
92
55
  currentPath: "/",
93
56
  viewMode: "list",
@@ -155,13 +118,9 @@ const useFileExplorerState = create((set, get) => ({
155
118
  }));
156
119
  export {
157
120
  DialogRoot as D,
158
- MenuRoot as M,
159
121
  DialogContent as a,
160
122
  DialogTitle as b,
161
123
  DialogDescription as c,
162
124
  DialogClose as d,
163
- MenuTrigger as e,
164
- MenuContent as f,
165
- MenuItem as g,
166
125
  useFileExplorerState as u
167
126
  };
@@ -184,7 +184,7 @@ function getResponse() {
184
184
  return event.res;
185
185
  }
186
186
  async function getStartManifest(matchedRoutes) {
187
- const { tsrStartManifest } = await import("./assets/_tanstack-start-manifest_v-CyfoMvUa.js");
187
+ const { tsrStartManifest } = await import("./assets/_tanstack-start-manifest_v-D5UVTs1o.js");
188
188
  const startManifest = tsrStartManifest();
189
189
  const rootRoute = startManifest.routes[rootRouteId] = startManifest.routes[rootRouteId] || {};
190
190
  rootRoute.assets = rootRoute.assets || [];
@@ -656,7 +656,7 @@ function getStartResponseHeaders(opts) {
656
656
  let entriesPromise;
657
657
  let manifestPromise;
658
658
  async function loadEntries() {
659
- const routerEntry = await import("./assets/router-rn7pJO_D.js").then((n) => n.r);
659
+ const routerEntry = await import("./assets/router-Uuagl6O7.js").then((n) => n.r);
660
660
  const startEntry = await import("./assets/start-HYkvq4Ni.js");
661
661
  return { startEntry, routerEntry };
662
662
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencami",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "type": "module",
5
5
  "description": "OpenCami - A beautiful web client for OpenClaw",
6
6
  "bin": {
@@ -79,6 +79,7 @@
79
79
  "@tauri-apps/api": "^2.10.1",
80
80
  "@tauri-apps/cli": "^2.10.0",
81
81
  "@testing-library/dom": "^10.4.0",
82
+ "@testing-library/jest-dom": "^6.9.1",
82
83
  "@testing-library/react": "^16.2.0",
83
84
  "@types/node": "^22.10.2",
84
85
  "@types/react": "^19.2.0",
@@ -1 +0,0 @@
1
- import{r as p}from"./main-B3N0eQFg.js";import{N as T,i as y}from"./useButton-Bnnac1eR.js";const E=[];function H(t){p.useEffect(t,E)}const a=typeof navigator<"u",u=w(),h=R(),b=S(),$=typeof CSS>"u"||!CSS.supports?!1:CSS.supports("-webkit-backdrop-filter:none"),q=u.platform==="MacIntel"&&u.maxTouchPoints>1?!0:/iP(hone|ad|od)|iOS/.test(u.platform),z=a&&/apple/i.test(navigator.vendor),c=a&&/android/i.test(h)||/android/i.test(b),G=a&&h.toLowerCase().startsWith("mac")&&!navigator.maxTouchPoints,A=b.includes("jsdom/");function w(){if(!a)return{platform:"",maxTouchPoints:-1};const t=navigator.userAgentData;return t?.platform?{platform:t.platform,maxTouchPoints:navigator.maxTouchPoints}:{platform:navigator.platform??"",maxTouchPoints:navigator.maxTouchPoints??-1}}function S(){if(!a)return"";const t=navigator.userAgentData;return t&&Array.isArray(t.brands)?t.brands.map(({brand:n,version:e})=>`${n}/${e}`).join(" "):navigator.userAgent}function R(){if(!a)return"";const t=navigator.userAgentData;return t?.platform?t.platform:navigator.platform??""}const m="data-base-ui-focusable",J="active",Q="selected",D="input:not([type='hidden']):not([disabled]),[contenteditable]:not([contenteditable='false']),textarea:not([disabled])",X="ArrowLeft",Z="ArrowRight",tt="ArrowUp",nt="ArrowDown";function et(t){let n=t.activeElement;for(;n?.shadowRoot?.activeElement!=null;)n=n.shadowRoot.activeElement;return n}function ot(t,n){if(!t||!n)return!1;const e=n.getRootNode?.();if(t.contains(n))return!0;if(e&&T(e)){let o=n;for(;o;){if(t===o)return!0;o=o.parentNode||o.host}}return!1}function rt(t){return"composedPath"in t?t.composedPath()[0]:t.target}function st(t,n){if(n==null)return!1;if("composedPath"in t)return t.composedPath().includes(n);const e=t;return e.target!=null&&n.contains(e.target)}function it(t){return t.matches("html,body")}function at(t){return t?.ownerDocument||document}function O(t){return y(t)&&t.matches(D)}function ut(t){return t?t.getAttribute("role")==="combobox"&&O(t):!1}function ct(t){if(!t||A)return!0;try{return t.matches(":focus-visible")}catch{return!0}}function ft(t){return t?t.hasAttribute(m)?t:t.querySelector(`[${m}]`)||t:null}function lt(t){t.preventDefault(),t.stopPropagation()}function pt(t){return"nativeEvent"in t}function mt(t){return t.mozInputSource===0&&t.isTrusted?!0:c&&t.pointerType?t.type==="click"&&t.buttons===1:t.detail===0&&!t.pointerType}function gt(t){return A?!1:!c&&t.width===0&&t.height===0||c&&t.width===1&&t.height===1&&t.pressure===0&&t.detail===0&&t.pointerType==="mouse"||t.width<1&&t.height<1&&t.pressure===0&&t.detail===0&&t.pointerType==="touch"}function dt(t,n){const e=["mouse","pen"];return n||e.push("",void 0),e.includes(t)}function ht(t){const n=t.type;return n==="click"||n==="mousedown"||n==="keydown"||n==="keyup"}const bt=["top","right","bottom","left"],C=Math.min,M=Math.max,At=Math.round,xt=Math.floor,Pt=t=>({x:t,y:t}),L={left:"right",right:"left",bottom:"top",top:"bottom"},k={start:"end",end:"start"};function Tt(t,n,e){return M(t,C(n,e))}function yt(t,n){return typeof t=="function"?t(n):t}function x(t){return t.split("-")[0]}function P(t){return t.split("-")[1]}function v(t){return t==="x"?"y":"x"}function W(t){return t==="y"?"height":"width"}const _=new Set(["top","bottom"]);function N(t){return _.has(x(t))?"y":"x"}function I(t){return v(N(t))}function Et(t,n,e){e===void 0&&(e=!1);const o=P(t),s=I(t),r=W(s);let i=s==="x"?o===(e?"end":"start")?"right":"left":o==="start"?"bottom":"top";return n.reference[r]>n.floating[r]&&(i=l(i)),[i,l(i)]}function wt(t){const n=l(t);return[f(t),n,f(n)]}function f(t){return t.replace(/start|end/g,n=>k[n])}const g=["left","right"],d=["right","left"],F=["top","bottom"],U=["bottom","top"];function j(t,n,e){switch(t){case"top":case"bottom":return e?n?d:g:n?g:d;case"left":case"right":return n?F:U;default:return[]}}function St(t,n,e,o){const s=P(t);let r=j(x(t),e==="start",o);return s&&(r=r.map(i=>i+"-"+s),n&&(r=r.concat(r.map(f)))),r}function l(t){return t.replace(/left|right|bottom|top/g,n=>L[n])}function V(t){return{top:0,right:0,bottom:0,left:0,...t}}function Rt(t){return typeof t!="number"?V(t):{top:t,right:t,bottom:t,left:t}}function Dt(t){const{x:n,y:e,width:o,height:s}=t;return{width:o,height:s,top:e,left:n,right:n+o,bottom:e+s,x:n,y:e}}function Ot(t){return t?.ownerDocument||document}const Y=p.createContext(void 0);function Ct(){return p.useContext(Y)?.direction??"ltr"}export{nt as A,wt as B,St as C,Et as D,P as E,C as F,M as G,bt as H,I,Rt as J,Dt as K,W as L,Tt as M,v as N,Pt as O,At as P,pt as Q,it as R,st as S,ct as T,G as U,D as V,m as W,J as X,Q as Y,Ct as a,ut as b,ot as c,ft as d,et as e,mt as f,at as g,gt as h,$ as i,rt as j,dt as k,ht as l,O as m,X as n,Z as o,tt as p,Ot as q,q as r,lt as s,xt as t,H as u,z as v,yt as w,x,N as y,l as z};