@dipertq/dsh-openviking-status 0.1.7 → 0.2.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/README.md +11 -3
- package/lib/client.cjs +1103 -367
- package/lib/client.cjs.map +1 -1
- package/lib/client.d.cts +186 -36
- package/lib/client.js +1100 -367
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +32 -4
- package/lib/index.js +1206 -5
- package/lib/index.js.map +1 -1
- package/package.json +6 -2
package/lib/client.js
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
1
8
|
// src/client/OpenVikingStatusChip.tsx
|
|
2
|
-
import {
|
|
9
|
+
import React2, {
|
|
3
10
|
useState as useState2,
|
|
4
11
|
useEffect as useEffect2,
|
|
5
12
|
useCallback as useCallback2,
|
|
6
13
|
useRef as useRef2,
|
|
7
14
|
useMemo
|
|
8
15
|
} from "react";
|
|
16
|
+
import ReactDOM from "react-dom";
|
|
9
17
|
|
|
10
18
|
// src/client/api.ts
|
|
11
19
|
var DEFAULT_OPENVIKING_ENDPOINT = "http://127.0.0.1:1933";
|
|
@@ -59,6 +67,30 @@ var OpenVikingClient = class {
|
|
|
59
67
|
this.endpoint = resolveEndpoint(endpoint);
|
|
60
68
|
this.apiKey = resolveApiKey(apiKey);
|
|
61
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Обновление конфигурации клиента на лету (например, после сохранения настроек в UI).
|
|
72
|
+
*/
|
|
73
|
+
updateConfig(config) {
|
|
74
|
+
if (config.endpoint && config.endpoint.trim()) {
|
|
75
|
+
this.endpoint = resolveEndpoint(config.endpoint);
|
|
76
|
+
}
|
|
77
|
+
if (config.apiKey !== void 0) {
|
|
78
|
+
this.apiKey = resolveApiKey(config.apiKey);
|
|
79
|
+
}
|
|
80
|
+
this.resolvedSessionIds.clear();
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Очистить кэш разрешенных идентификаторов сессий.
|
|
84
|
+
*/
|
|
85
|
+
clearResolvedSessions() {
|
|
86
|
+
this.resolvedSessionIds.clear();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Проверка, работает ли клиент через DSH Web Server proxy.
|
|
90
|
+
*/
|
|
91
|
+
isProxy() {
|
|
92
|
+
return this.endpoint.startsWith("/") || this.endpoint.includes("/openviking-status/api");
|
|
93
|
+
}
|
|
62
94
|
/**
|
|
63
95
|
* Формирование заголовков запроса, включая опциональный заголовок авторизации
|
|
64
96
|
*/
|
|
@@ -89,6 +121,8 @@ var OpenVikingClient = class {
|
|
|
89
121
|
} else if (raw.startsWith("dsh-")) {
|
|
90
122
|
const suffix = raw.slice("dsh-".length);
|
|
91
123
|
candidates.push(raw, `dsh-session-${suffix}`);
|
|
124
|
+
} else if (raw.startsWith("session-")) {
|
|
125
|
+
candidates.push(`dsh-${raw}`, raw);
|
|
92
126
|
} else {
|
|
93
127
|
candidates.push(`dsh-session-${raw}`, `dsh-${raw}`, raw);
|
|
94
128
|
}
|
|
@@ -98,6 +132,32 @@ var OpenVikingClient = class {
|
|
|
98
132
|
* Проверка доступности и состояния сервиса OpenViking
|
|
99
133
|
*/
|
|
100
134
|
async checkHealth() {
|
|
135
|
+
if (this.isProxy()) {
|
|
136
|
+
try {
|
|
137
|
+
const res = await fetch(`${this.endpoint}/health`, {
|
|
138
|
+
method: "GET",
|
|
139
|
+
headers: this.getHeaders()
|
|
140
|
+
});
|
|
141
|
+
if (!res.ok) {
|
|
142
|
+
return {
|
|
143
|
+
ok: false,
|
|
144
|
+
error: `HTTP ${res.status}: ${res.statusText}`
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
const body = await res.json().catch(() => ({}));
|
|
148
|
+
const isOk = body.ok !== false && body.status !== "error" && (body.ok === true || body.status === "ok" || body.status === "healthy" || res.ok);
|
|
149
|
+
return {
|
|
150
|
+
ok: isOk,
|
|
151
|
+
version: typeof body.version === "string" ? body.version : void 0,
|
|
152
|
+
storage: typeof body.storage === "string" ? body.storage : void 0
|
|
153
|
+
};
|
|
154
|
+
} catch (err) {
|
|
155
|
+
return {
|
|
156
|
+
ok: false,
|
|
157
|
+
error: err instanceof Error ? err.message : String(err)
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
101
161
|
try {
|
|
102
162
|
const res = await fetch(`${this.endpoint}/health`, {
|
|
103
163
|
method: "GET",
|
|
@@ -124,12 +184,58 @@ var OpenVikingClient = class {
|
|
|
124
184
|
}
|
|
125
185
|
}
|
|
126
186
|
/**
|
|
127
|
-
*
|
|
128
|
-
*
|
|
187
|
+
* Чтение метаданных сессии с явной причиной неудачи.
|
|
188
|
+
*
|
|
189
|
+
* Демон может работать с `auth_mode: api_key`: тогда `/health` остаётся
|
|
190
|
+
* открытым, а сессия отвечает 401. Схлопывать это в «нет данных» нельзя —
|
|
191
|
+
* иначе интерфейс покажет живой индикатор рядом с нулями и умолчит о том,
|
|
192
|
+
* что счётчики просто недоступны.
|
|
129
193
|
*/
|
|
130
|
-
async
|
|
194
|
+
async readSession(sessionId) {
|
|
131
195
|
if (!sessionId || !sessionId.trim()) {
|
|
132
|
-
return
|
|
196
|
+
return { status: "missing" };
|
|
197
|
+
}
|
|
198
|
+
if (this.isProxy()) {
|
|
199
|
+
try {
|
|
200
|
+
const res = await fetch(
|
|
201
|
+
`${this.endpoint}/session?id=${encodeURIComponent(sessionId.trim())}`,
|
|
202
|
+
{
|
|
203
|
+
method: "GET",
|
|
204
|
+
headers: this.getHeaders()
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
if (res.status === 401 || res.status === 403) {
|
|
208
|
+
return { status: "unauthorized" };
|
|
209
|
+
}
|
|
210
|
+
if (!res.ok) {
|
|
211
|
+
return { status: "error", detail: `HTTP ${res.status}` };
|
|
212
|
+
}
|
|
213
|
+
const data = await res.json();
|
|
214
|
+
if (data.status === "unauthorized") return { status: "unauthorized" };
|
|
215
|
+
if (data.status === "missing") return { status: "missing" };
|
|
216
|
+
if (data.status === "unreachable")
|
|
217
|
+
return {
|
|
218
|
+
status: "unreachable",
|
|
219
|
+
detail: typeof data.detail === "string" ? data.detail : void 0
|
|
220
|
+
};
|
|
221
|
+
if (data.status === "error")
|
|
222
|
+
return {
|
|
223
|
+
status: "error",
|
|
224
|
+
detail: typeof data.detail === "string" ? data.detail : void 0
|
|
225
|
+
};
|
|
226
|
+
if (data.status === "ok" && data.session) {
|
|
227
|
+
return {
|
|
228
|
+
status: "ok",
|
|
229
|
+
session: data.session
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
return { status: "error", detail: "malformed response from proxy" };
|
|
233
|
+
} catch (err) {
|
|
234
|
+
return {
|
|
235
|
+
status: "unreachable",
|
|
236
|
+
detail: err instanceof Error ? err.message : String(err)
|
|
237
|
+
};
|
|
238
|
+
}
|
|
133
239
|
}
|
|
134
240
|
const candidates = this.getCandidateSessionIds(sessionId);
|
|
135
241
|
for (const candidateId of candidates) {
|
|
@@ -144,30 +250,48 @@ var OpenVikingClient = class {
|
|
|
144
250
|
if (res.status === 404) {
|
|
145
251
|
continue;
|
|
146
252
|
}
|
|
253
|
+
if (res.status === 401 || res.status === 403) {
|
|
254
|
+
return { status: "unauthorized" };
|
|
255
|
+
}
|
|
147
256
|
if (!res.ok) {
|
|
148
|
-
return
|
|
257
|
+
return { status: "error", detail: `HTTP ${res.status}` };
|
|
149
258
|
}
|
|
150
259
|
const data = await res.json();
|
|
151
260
|
const raw = data?.result ?? data?.data ?? data;
|
|
152
261
|
if (!raw || typeof raw !== "object") {
|
|
153
|
-
return
|
|
262
|
+
return { status: "error", detail: "malformed response body" };
|
|
154
263
|
}
|
|
155
264
|
this.resolvedSessionIds.set(sessionId.trim(), candidateId);
|
|
156
265
|
return {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
266
|
+
status: "ok",
|
|
267
|
+
session: {
|
|
268
|
+
session_id: typeof raw.session_id === "string" ? raw.session_id : candidateId,
|
|
269
|
+
peer_id: typeof raw.peer_id === "string" ? raw.peer_id : void 0,
|
|
270
|
+
pending_tokens: typeof raw.pending_tokens === "number" ? raw.pending_tokens : 0,
|
|
271
|
+
message_count: typeof raw.message_count === "number" ? raw.message_count : void 0,
|
|
272
|
+
commit_count: typeof raw.commit_count === "number" ? raw.commit_count : void 0,
|
|
273
|
+
last_commit_at: typeof raw.last_commit_at === "string" ? raw.last_commit_at : typeof raw.last_commit === "string" ? raw.last_commit : void 0,
|
|
274
|
+
created_at: typeof raw.created_at === "string" ? raw.created_at : void 0,
|
|
275
|
+
updated_at: typeof raw.updated_at === "string" ? raw.updated_at : void 0
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
} catch (err) {
|
|
279
|
+
return {
|
|
280
|
+
status: "unreachable",
|
|
281
|
+
detail: err instanceof Error ? err.message : String(err)
|
|
165
282
|
};
|
|
166
|
-
} catch {
|
|
167
|
-
return null;
|
|
168
283
|
}
|
|
169
284
|
}
|
|
170
|
-
return
|
|
285
|
+
return { status: "missing" };
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Получение метаданных сессии по идентификатору.
|
|
289
|
+
* Обёртка над {@link readSession} для вызывающих, которым причина неудачи
|
|
290
|
+
* не нужна: любая неудача сводится к null.
|
|
291
|
+
*/
|
|
292
|
+
async fetchSession(sessionId) {
|
|
293
|
+
const result = await this.readSession(sessionId);
|
|
294
|
+
return result.status === "ok" ? result.session : null;
|
|
171
295
|
}
|
|
172
296
|
/**
|
|
173
297
|
* Алиас для fetchSession
|
|
@@ -182,6 +306,31 @@ var OpenVikingClient = class {
|
|
|
182
306
|
if (!sessionId || !sessionId.trim()) {
|
|
183
307
|
return { ok: false, error: "Missing sessionId" };
|
|
184
308
|
}
|
|
309
|
+
if (this.isProxy()) {
|
|
310
|
+
try {
|
|
311
|
+
const res = await fetch(`${this.endpoint}/session/commit`, {
|
|
312
|
+
method: "POST",
|
|
313
|
+
headers: this.getHeaders(),
|
|
314
|
+
body: JSON.stringify({
|
|
315
|
+
sessionId: sessionId.trim(),
|
|
316
|
+
...options ?? { keep_recent_count: 10 }
|
|
317
|
+
})
|
|
318
|
+
});
|
|
319
|
+
if (!res.ok) {
|
|
320
|
+
return { ok: false, error: `HTTP ${res.status}` };
|
|
321
|
+
}
|
|
322
|
+
const data = await res.json().catch(() => ({}));
|
|
323
|
+
return {
|
|
324
|
+
ok: data.ok === true,
|
|
325
|
+
error: typeof data.error === "string" ? data.error : void 0
|
|
326
|
+
};
|
|
327
|
+
} catch (err) {
|
|
328
|
+
return {
|
|
329
|
+
ok: false,
|
|
330
|
+
error: err instanceof Error ? err.message : String(err)
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
}
|
|
185
334
|
const candidates = this.getCandidateSessionIds(sessionId);
|
|
186
335
|
const bodyPayload = JSON.stringify(options ?? { keep_recent_count: 10 });
|
|
187
336
|
let lastError = "Session commit failed";
|
|
@@ -233,6 +382,45 @@ function commitSession(sessionId, options, endpoint, apiKey) {
|
|
|
233
382
|
return client.commitSession(sessionId, options);
|
|
234
383
|
}
|
|
235
384
|
|
|
385
|
+
// src/client/theme.ts
|
|
386
|
+
var THEME = {
|
|
387
|
+
/** Фон всплывающей панели — тот же, что у меню и диалогов DSH. */
|
|
388
|
+
panelSurface: "--dsw-specific-menu",
|
|
389
|
+
/** Тень панели. */
|
|
390
|
+
panelElevation: "--dsw-elevation-prominent",
|
|
391
|
+
/** Контур панели; задаётся через переменную тени, а не через border. */
|
|
392
|
+
panelStroke: "--dsw-alias-border-l1",
|
|
393
|
+
/** Заголовки и акцентный текст. */
|
|
394
|
+
labelPrimary: "--dsw-alias-label-primary",
|
|
395
|
+
/** Основной текст панели. */
|
|
396
|
+
labelSecondary: "--dsw-alias-label-secondary",
|
|
397
|
+
/** Приглушённый текст: подписи, значения, текст чипа в покое. */
|
|
398
|
+
labelTertiary: "--dsw-alias-label-tertiary",
|
|
399
|
+
/** Разделительная линия внутри панели. */
|
|
400
|
+
hairline: "--dsw-alias-border-l2",
|
|
401
|
+
/** Подсветка интерактивного элемента под курсором. */
|
|
402
|
+
hoverBackground: "--dsw-alias-interactive-bg-hover",
|
|
403
|
+
/** Подсветка нажатого элемента. */
|
|
404
|
+
activeBackground: "--dsw-alias-interactive-bg-active",
|
|
405
|
+
/** Демон доступен. */
|
|
406
|
+
stateSuccess: "--dsw-alias-state-success-primary",
|
|
407
|
+
/** Демон недоступен или сессия нечитаема. */
|
|
408
|
+
stateError: "--dsw-alias-state-error-primary",
|
|
409
|
+
/** Идёт коммит, либо накоплено близко к порогу. */
|
|
410
|
+
stateWarning: "--dsw-alias-state-warn-primary",
|
|
411
|
+
/** Утопленная поверхность: дорожка прогресс-бара. */
|
|
412
|
+
insetSurface: "--dsw-alias-bg-layer-2",
|
|
413
|
+
/** Заливка основной кнопки действий. */
|
|
414
|
+
buttonPrimaryFill: "--dsw-alias-button-primary-fill",
|
|
415
|
+
/** Цвет текста на основной кнопке действий. */
|
|
416
|
+
buttonPrimaryText: "--dsw-alias-label-primary-inverted",
|
|
417
|
+
/** Моноширинный шрифт для идентификаторов и путей. */
|
|
418
|
+
fontMono: "--dsw-font-markdown-code-font-family"
|
|
419
|
+
};
|
|
420
|
+
function themeVar(role) {
|
|
421
|
+
return `var(${THEME[role]})`;
|
|
422
|
+
}
|
|
423
|
+
|
|
236
424
|
// src/client/recallParser.ts
|
|
237
425
|
var KNOWN_CATEGORIES = /* @__PURE__ */ new Set([
|
|
238
426
|
"preferences",
|
|
@@ -541,6 +729,15 @@ function parseRecalledMemories(input) {
|
|
|
541
729
|
// src/client/OpenVikingStatusPopover.tsx
|
|
542
730
|
import { useState, useEffect, useCallback, useRef } from "react";
|
|
543
731
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
732
|
+
function dshIcon(name2) {
|
|
733
|
+
try {
|
|
734
|
+
const primitives = typeof __require === "function" ? __require("@deepseek-ai/dsh-client-ui-primitives") : null;
|
|
735
|
+
const icon = primitives?.[name2];
|
|
736
|
+
return typeof icon === "function" ? icon : null;
|
|
737
|
+
} catch {
|
|
738
|
+
return null;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
544
741
|
function getProgressBarPercent(pendingTokens, threshold = COMMIT_THRESHOLD) {
|
|
545
742
|
if (!threshold || threshold <= 0) return 0;
|
|
546
743
|
const ratio = (pendingTokens || 0) / threshold;
|
|
@@ -548,9 +745,14 @@ function getProgressBarPercent(pendingTokens, threshold = COMMIT_THRESHOLD) {
|
|
|
548
745
|
}
|
|
549
746
|
function getProgressBarColor(percent) {
|
|
550
747
|
if (percent >= 80) {
|
|
551
|
-
return "
|
|
748
|
+
return themeVar("stateWarning");
|
|
552
749
|
}
|
|
553
|
-
return "
|
|
750
|
+
return themeVar("stateSuccess");
|
|
751
|
+
}
|
|
752
|
+
function formatDaemonVersion(version) {
|
|
753
|
+
const value = version?.trim();
|
|
754
|
+
if (!value) return void 0;
|
|
755
|
+
return /^v/i.test(value) ? value : `v${value}`;
|
|
554
756
|
}
|
|
555
757
|
function formatRelativeTime(isoOrTimestamp, now = Date.now()) {
|
|
556
758
|
if (!isoOrTimestamp) return void 0;
|
|
@@ -592,39 +794,8 @@ function truncateSessionId(id, maxLen = 16) {
|
|
|
592
794
|
if (id.length <= maxLen) return id;
|
|
593
795
|
return `${id.slice(0, maxLen)}...`;
|
|
594
796
|
}
|
|
595
|
-
function getCategoryBadgeStyle(
|
|
596
|
-
|
|
597
|
-
case "preferences":
|
|
598
|
-
return {
|
|
599
|
-
backgroundColor: "rgba(168, 85, 247, 0.15)",
|
|
600
|
-
color: "var(--dsw-status-purple, #c084fc)"
|
|
601
|
-
};
|
|
602
|
-
case "entities":
|
|
603
|
-
return {
|
|
604
|
-
backgroundColor: "rgba(59, 130, 246, 0.15)",
|
|
605
|
-
color: "var(--dsw-status-info, #60a5fa)"
|
|
606
|
-
};
|
|
607
|
-
case "skills":
|
|
608
|
-
return {
|
|
609
|
-
backgroundColor: "rgba(236, 72, 153, 0.15)",
|
|
610
|
-
color: "var(--dsw-status-pink, #f472b6)"
|
|
611
|
-
};
|
|
612
|
-
case "events":
|
|
613
|
-
return {
|
|
614
|
-
backgroundColor: "rgba(245, 158, 11, 0.15)",
|
|
615
|
-
color: "var(--dsw-status-warning, #fbbf24)"
|
|
616
|
-
};
|
|
617
|
-
case "resources":
|
|
618
|
-
return {
|
|
619
|
-
backgroundColor: "rgba(20, 184, 166, 0.15)",
|
|
620
|
-
color: "var(--dsw-status-teal, #2dd4bf)"
|
|
621
|
-
};
|
|
622
|
-
default:
|
|
623
|
-
return {
|
|
624
|
-
backgroundColor: "rgba(148, 163, 184, 0.15)",
|
|
625
|
-
color: "var(--dsw-text-muted, #94a3b8)"
|
|
626
|
-
};
|
|
627
|
-
}
|
|
797
|
+
function getCategoryBadgeStyle(_category) {
|
|
798
|
+
return { color: themeVar("labelTertiary") };
|
|
628
799
|
}
|
|
629
800
|
function handleEscapeKey(event, onClose) {
|
|
630
801
|
if (event.key === "Escape") {
|
|
@@ -637,6 +808,7 @@ function OpenVikingStatusPopover({
|
|
|
637
808
|
sessionId,
|
|
638
809
|
health,
|
|
639
810
|
sessionData,
|
|
811
|
+
sessionRead,
|
|
640
812
|
recalledResult,
|
|
641
813
|
endpoint,
|
|
642
814
|
isCommitting = false,
|
|
@@ -656,13 +828,17 @@ function OpenVikingStatusPopover({
|
|
|
656
828
|
};
|
|
657
829
|
}, []);
|
|
658
830
|
const isOnline = health?.ok === true;
|
|
659
|
-
const
|
|
831
|
+
const sessionUnreadable = isOnline && sessionRead != null && sessionRead.status !== "ok";
|
|
832
|
+
const unauthorized = sessionRead?.status === "unauthorized";
|
|
833
|
+
const statusColor = isOnline ? sessionUnreadable ? themeVar("stateWarning") : themeVar("stateSuccess") : themeVar("stateError");
|
|
660
834
|
const displaySessionId = sessionData?.session_id || sessionId || "";
|
|
661
835
|
const pendingTokens = sessionData?.pending_tokens ?? 0;
|
|
662
836
|
const progressPercent = getProgressBarPercent(pendingTokens);
|
|
663
837
|
const progressBarColor = getProgressBarColor(progressPercent);
|
|
664
838
|
const memoryItems = recalledResult?.items || [];
|
|
665
839
|
const recalledCount = recalledResult?.recalledCount ?? memoryItems.length;
|
|
840
|
+
const CopyIcon = dshIcon("IconCopyOutline16");
|
|
841
|
+
const CheckIcon = dshIcon("IconCheckOutline16");
|
|
666
842
|
const handleCopySessionId = useCallback(() => {
|
|
667
843
|
if (!displaySessionId) return;
|
|
668
844
|
if (typeof navigator !== "undefined" && navigator.clipboard) {
|
|
@@ -678,7 +854,15 @@ function OpenVikingStatusPopover({
|
|
|
678
854
|
}, 1500);
|
|
679
855
|
}
|
|
680
856
|
}, [displaySessionId]);
|
|
681
|
-
const isCommitDisabled = isCommitting || !isOnline || pendingTokens === 0;
|
|
857
|
+
const isCommitDisabled = isCommitting || !isOnline || sessionUnreadable || pendingTokens === 0;
|
|
858
|
+
const pendingLabel = sessionUnreadable ? "unavailable" : `${pendingTokens.toLocaleString()} / ${COMMIT_THRESHOLD.toLocaleString()}`;
|
|
859
|
+
const rowStyle = {
|
|
860
|
+
display: "flex",
|
|
861
|
+
justifyContent: "space-between",
|
|
862
|
+
alignItems: "center"
|
|
863
|
+
};
|
|
864
|
+
const mutedStyle = { color: themeVar("labelTertiary") };
|
|
865
|
+
const monoStyle = { fontFamily: themeVar("fontMono") };
|
|
682
866
|
return /* @__PURE__ */ jsxs(
|
|
683
867
|
"div",
|
|
684
868
|
{
|
|
@@ -689,17 +873,23 @@ function OpenVikingStatusPopover({
|
|
|
689
873
|
position: "absolute",
|
|
690
874
|
bottom: "calc(100% + 8px)",
|
|
691
875
|
right: 0,
|
|
692
|
-
|
|
693
|
-
backgroundColor: "var(--dsw-surface-overlay, #1e293b)",
|
|
694
|
-
border: "1px solid var(--dsw-border-default, #334155)",
|
|
695
|
-
borderRadius: "8px",
|
|
696
|
-
padding: "12px",
|
|
697
|
-
boxShadow: "0 10px 25px -5px rgba(0, 0, 0, 0.5)",
|
|
698
|
-
zIndex: 1e3,
|
|
699
|
-
fontSize: "12px",
|
|
700
|
-
color: "var(--dsw-text-default, #f1f5f9)",
|
|
701
|
-
fontFamily: "var(--dsw-font-sans, system-ui, sans-serif)",
|
|
876
|
+
zIndex: 1100,
|
|
702
877
|
boxSizing: "border-box",
|
|
878
|
+
width: "max-content",
|
|
879
|
+
minWidth: "min(300px, 100vw - 24px)",
|
|
880
|
+
maxWidth: "min(440px, 100vw - 24px)",
|
|
881
|
+
background: themeVar("panelSurface"),
|
|
882
|
+
boxShadow: themeVar("panelElevation"),
|
|
883
|
+
color: themeVar("labelSecondary"),
|
|
884
|
+
cursor: "default",
|
|
885
|
+
border: 0,
|
|
886
|
+
borderRadius: "12px",
|
|
887
|
+
padding: "16px",
|
|
888
|
+
fontSize: "12px",
|
|
889
|
+
lineHeight: "18px",
|
|
890
|
+
...{
|
|
891
|
+
"--dsw-elevation-stroke-color": themeVar("panelStroke")
|
|
892
|
+
},
|
|
703
893
|
...style
|
|
704
894
|
},
|
|
705
895
|
children: [
|
|
@@ -710,58 +900,41 @@ function OpenVikingStatusPopover({
|
|
|
710
900
|
style: {
|
|
711
901
|
display: "flex",
|
|
712
902
|
justifyContent: "space-between",
|
|
713
|
-
|
|
714
|
-
marginBottom: "
|
|
715
|
-
|
|
716
|
-
|
|
903
|
+
gap: "16px",
|
|
904
|
+
marginBottom: "8px",
|
|
905
|
+
color: themeVar("labelPrimary"),
|
|
906
|
+
fontWeight: 500
|
|
717
907
|
},
|
|
718
908
|
children: [
|
|
719
|
-
/* @__PURE__ */ jsxs("
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
{
|
|
723
|
-
style: {
|
|
724
|
-
fontWeight: 600,
|
|
725
|
-
fontSize: "13px",
|
|
726
|
-
color: "var(--dsw-text-default, #f1f5f9)"
|
|
727
|
-
},
|
|
728
|
-
children: "OpenViking Memory"
|
|
729
|
-
}
|
|
730
|
-
),
|
|
909
|
+
/* @__PURE__ */ jsxs("span", { style: { minWidth: 0 }, children: [
|
|
910
|
+
"OpenViking Memory",
|
|
911
|
+
" ",
|
|
731
912
|
/* @__PURE__ */ jsx(
|
|
732
|
-
"
|
|
913
|
+
"span",
|
|
733
914
|
{
|
|
734
915
|
"data-testid": "endpoint-label",
|
|
735
|
-
style: {
|
|
736
|
-
fontSize: "10px",
|
|
737
|
-
color: "var(--dsw-text-muted, #94a3b8)",
|
|
738
|
-
fontFamily: "var(--dsw-font-mono, monospace)",
|
|
739
|
-
marginTop: "1px"
|
|
740
|
-
},
|
|
916
|
+
style: { ...mutedStyle, ...monoStyle, fontWeight: 400 },
|
|
741
917
|
children: formatEndpoint(endpoint)
|
|
742
918
|
}
|
|
743
919
|
)
|
|
744
920
|
] }),
|
|
745
921
|
/* @__PURE__ */ jsxs(
|
|
746
|
-
"
|
|
922
|
+
"span",
|
|
747
923
|
{
|
|
748
924
|
"data-testid": "status-badge",
|
|
749
925
|
style: {
|
|
750
926
|
display: "inline-flex",
|
|
751
927
|
alignItems: "center",
|
|
752
|
-
gap: "
|
|
753
|
-
fontSize: "10px",
|
|
754
|
-
padding: "2px 7px",
|
|
755
|
-
borderRadius: "4px",
|
|
756
|
-
backgroundColor: isOnline ? "rgba(52, 211, 153, 0.15)" : "rgba(248, 113, 113, 0.15)",
|
|
928
|
+
gap: "6px",
|
|
757
929
|
color: statusColor,
|
|
758
|
-
|
|
930
|
+
flexShrink: 0
|
|
759
931
|
},
|
|
760
932
|
children: [
|
|
761
933
|
/* @__PURE__ */ jsx(
|
|
762
934
|
"span",
|
|
763
935
|
{
|
|
764
936
|
"data-testid": "status-badge-dot",
|
|
937
|
+
"aria-hidden": "true",
|
|
765
938
|
style: {
|
|
766
939
|
width: "6px",
|
|
767
940
|
height: "6px",
|
|
@@ -771,13 +944,27 @@ function OpenVikingStatusPopover({
|
|
|
771
944
|
}
|
|
772
945
|
}
|
|
773
946
|
),
|
|
774
|
-
/* @__PURE__ */ jsx("span", { children: isOnline ?
|
|
947
|
+
/* @__PURE__ */ jsx("span", { children: isOnline ? [
|
|
948
|
+
"ONLINE",
|
|
949
|
+
formatDaemonVersion(health?.version),
|
|
950
|
+
sessionUnreadable ? "\xB7 no session access" : null
|
|
951
|
+
].filter(Boolean).join(" ") : "OFFLINE" })
|
|
775
952
|
]
|
|
776
953
|
}
|
|
777
954
|
)
|
|
778
955
|
]
|
|
779
956
|
}
|
|
780
957
|
),
|
|
958
|
+
/* @__PURE__ */ jsx(
|
|
959
|
+
"div",
|
|
960
|
+
{
|
|
961
|
+
style: {
|
|
962
|
+
borderTop: `.5px solid ${themeVar("hairline")}`,
|
|
963
|
+
marginBottom: "10px"
|
|
964
|
+
},
|
|
965
|
+
"aria-hidden": "true"
|
|
966
|
+
}
|
|
967
|
+
),
|
|
781
968
|
/* @__PURE__ */ jsxs(
|
|
782
969
|
"div",
|
|
783
970
|
{
|
|
@@ -788,142 +975,88 @@ function OpenVikingStatusPopover({
|
|
|
788
975
|
marginBottom: "10px"
|
|
789
976
|
},
|
|
790
977
|
children: [
|
|
791
|
-
/* @__PURE__ */ jsxs(
|
|
792
|
-
"
|
|
793
|
-
{
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
alignItems: "center"
|
|
865
|
-
},
|
|
866
|
-
children: [
|
|
867
|
-
/* @__PURE__ */ jsx("span", { style: { color: "var(--dsw-text-muted, #94a3b8)" }, children: "Peer ID:" }),
|
|
868
|
-
/* @__PURE__ */ jsx(
|
|
869
|
-
"span",
|
|
870
|
-
{
|
|
871
|
-
"data-testid": "peer-id-value",
|
|
872
|
-
style: {
|
|
873
|
-
maxWidth: "180px",
|
|
874
|
-
overflow: "hidden",
|
|
875
|
-
textOverflow: "ellipsis",
|
|
876
|
-
whiteSpace: "nowrap",
|
|
877
|
-
fontFamily: "var(--dsw-font-mono, monospace)"
|
|
878
|
-
},
|
|
879
|
-
title: sessionData.peer_id,
|
|
880
|
-
children: sessionData.peer_id
|
|
881
|
-
}
|
|
882
|
-
)
|
|
883
|
-
]
|
|
884
|
-
}
|
|
885
|
-
),
|
|
886
|
-
sessionData?.last_commit_at && /* @__PURE__ */ jsxs(
|
|
887
|
-
"div",
|
|
888
|
-
{
|
|
889
|
-
style: {
|
|
890
|
-
display: "flex",
|
|
891
|
-
justifyContent: "space-between",
|
|
892
|
-
alignItems: "center"
|
|
893
|
-
},
|
|
894
|
-
children: [
|
|
895
|
-
/* @__PURE__ */ jsx("span", { style: { color: "var(--dsw-text-muted, #94a3b8)" }, children: "Last Commit:" }),
|
|
896
|
-
/* @__PURE__ */ jsx(
|
|
897
|
-
"span",
|
|
898
|
-
{
|
|
899
|
-
"data-testid": "last-commit-value",
|
|
900
|
-
title: sessionData.last_commit_at,
|
|
901
|
-
style: { color: "var(--dsw-text-default, #e2e8f0)" },
|
|
902
|
-
children: formatRelativeTime(sessionData.last_commit_at) || sessionData.last_commit_at
|
|
903
|
-
}
|
|
904
|
-
)
|
|
905
|
-
]
|
|
906
|
-
}
|
|
907
|
-
)
|
|
978
|
+
/* @__PURE__ */ jsxs("div", { style: rowStyle, children: [
|
|
979
|
+
/* @__PURE__ */ jsx("span", { style: mutedStyle, children: "Session ID:" }),
|
|
980
|
+
/* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [
|
|
981
|
+
/* @__PURE__ */ jsx(
|
|
982
|
+
"span",
|
|
983
|
+
{
|
|
984
|
+
"data-testid": "session-id-value",
|
|
985
|
+
role: "button",
|
|
986
|
+
tabIndex: 0,
|
|
987
|
+
onKeyDown: (e) => {
|
|
988
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
989
|
+
e.preventDefault();
|
|
990
|
+
handleCopySessionId();
|
|
991
|
+
}
|
|
992
|
+
},
|
|
993
|
+
"aria-label": "Click to copy Session ID",
|
|
994
|
+
style: { ...monoStyle, cursor: "pointer" },
|
|
995
|
+
title: displaySessionId,
|
|
996
|
+
onClick: handleCopySessionId,
|
|
997
|
+
children: truncateSessionId(displaySessionId)
|
|
998
|
+
}
|
|
999
|
+
),
|
|
1000
|
+
/* @__PURE__ */ jsx(
|
|
1001
|
+
"button",
|
|
1002
|
+
{
|
|
1003
|
+
type: "button",
|
|
1004
|
+
"data-testid": "copy-session-btn",
|
|
1005
|
+
onClick: handleCopySessionId,
|
|
1006
|
+
title: copied ? "Copied!" : "Copy Session ID",
|
|
1007
|
+
"aria-label": copied ? "Copied!" : "Copy Session ID",
|
|
1008
|
+
style: {
|
|
1009
|
+
background: "none",
|
|
1010
|
+
border: "none",
|
|
1011
|
+
cursor: "pointer",
|
|
1012
|
+
padding: "2px",
|
|
1013
|
+
display: "inline-flex",
|
|
1014
|
+
alignItems: "center",
|
|
1015
|
+
color: copied ? themeVar("stateSuccess") : themeVar("labelTertiary")
|
|
1016
|
+
},
|
|
1017
|
+
children: copied ? CheckIcon && /* @__PURE__ */ jsx(CheckIcon, { size: 14 }) : CopyIcon && /* @__PURE__ */ jsx(CopyIcon, { size: 14 })
|
|
1018
|
+
}
|
|
1019
|
+
)
|
|
1020
|
+
] })
|
|
1021
|
+
] }),
|
|
1022
|
+
sessionData?.peer_id && /* @__PURE__ */ jsxs("div", { style: rowStyle, children: [
|
|
1023
|
+
/* @__PURE__ */ jsx("span", { style: mutedStyle, children: "Peer ID:" }),
|
|
1024
|
+
/* @__PURE__ */ jsx(
|
|
1025
|
+
"span",
|
|
1026
|
+
{
|
|
1027
|
+
"data-testid": "peer-id-value",
|
|
1028
|
+
style: {
|
|
1029
|
+
...monoStyle,
|
|
1030
|
+
maxWidth: "180px",
|
|
1031
|
+
overflow: "hidden",
|
|
1032
|
+
textOverflow: "ellipsis",
|
|
1033
|
+
whiteSpace: "nowrap"
|
|
1034
|
+
},
|
|
1035
|
+
title: sessionData.peer_id,
|
|
1036
|
+
children: sessionData.peer_id
|
|
1037
|
+
}
|
|
1038
|
+
)
|
|
1039
|
+
] }),
|
|
1040
|
+
sessionData?.last_commit_at && /* @__PURE__ */ jsxs("div", { style: rowStyle, children: [
|
|
1041
|
+
/* @__PURE__ */ jsx("span", { style: mutedStyle, children: "Last Commit:" }),
|
|
1042
|
+
/* @__PURE__ */ jsx(
|
|
1043
|
+
"span",
|
|
1044
|
+
{
|
|
1045
|
+
"data-testid": "last-commit-value",
|
|
1046
|
+
title: sessionData.last_commit_at,
|
|
1047
|
+
children: formatRelativeTime(sessionData.last_commit_at) || sessionData.last_commit_at
|
|
1048
|
+
}
|
|
1049
|
+
)
|
|
1050
|
+
] })
|
|
908
1051
|
]
|
|
909
1052
|
}
|
|
910
1053
|
),
|
|
911
1054
|
/* @__PURE__ */ jsxs("div", { style: { marginBottom: "12px" }, children: [
|
|
912
|
-
/* @__PURE__ */ jsxs(
|
|
913
|
-
"
|
|
914
|
-
{
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
justifyContent: "space-between",
|
|
918
|
-
marginBottom: "4px"
|
|
919
|
-
},
|
|
920
|
-
children: [
|
|
921
|
-
/* @__PURE__ */ jsx("span", { style: { color: "var(--dsw-text-muted, #94a3b8)" }, children: "Pending Tokens:" }),
|
|
922
|
-
/* @__PURE__ */ jsx("span", { "data-testid": "pending-tokens-label", style: { fontWeight: 500 }, children: `${pendingTokens.toLocaleString()} / ${COMMIT_THRESHOLD.toLocaleString()}` })
|
|
923
|
-
]
|
|
924
|
-
}
|
|
925
|
-
),
|
|
926
|
-
/* @__PURE__ */ jsx(
|
|
1055
|
+
/* @__PURE__ */ jsxs("div", { style: { ...rowStyle, marginBottom: "4px" }, children: [
|
|
1056
|
+
/* @__PURE__ */ jsx("span", { style: mutedStyle, children: "Pending Tokens:" }),
|
|
1057
|
+
/* @__PURE__ */ jsx("span", { "data-testid": "pending-tokens-label", children: pendingLabel })
|
|
1058
|
+
] }),
|
|
1059
|
+
!sessionUnreadable && /* @__PURE__ */ jsx(
|
|
927
1060
|
"div",
|
|
928
1061
|
{
|
|
929
1062
|
"data-testid": "progress-bar-track",
|
|
@@ -931,7 +1064,7 @@ function OpenVikingStatusPopover({
|
|
|
931
1064
|
width: "100%",
|
|
932
1065
|
height: "6px",
|
|
933
1066
|
borderRadius: "3px",
|
|
934
|
-
backgroundColor: "
|
|
1067
|
+
backgroundColor: themeVar("insetSurface"),
|
|
935
1068
|
overflow: "hidden"
|
|
936
1069
|
},
|
|
937
1070
|
children: /* @__PURE__ */ jsx(
|
|
@@ -949,30 +1082,34 @@ function OpenVikingStatusPopover({
|
|
|
949
1082
|
}
|
|
950
1083
|
)
|
|
951
1084
|
] }),
|
|
1085
|
+
sessionUnreadable && /* @__PURE__ */ jsx(
|
|
1086
|
+
"div",
|
|
1087
|
+
{
|
|
1088
|
+
"data-testid": "session-unreadable-notice",
|
|
1089
|
+
style: {
|
|
1090
|
+
marginBottom: "12px",
|
|
1091
|
+
color: themeVar("labelTertiary")
|
|
1092
|
+
},
|
|
1093
|
+
children: unauthorized ? "The daemon requires an API key. Set openviking_api_key in localStorage to read session counters." : "Session counters are unavailable right now."
|
|
1094
|
+
}
|
|
1095
|
+
),
|
|
952
1096
|
/* @__PURE__ */ jsxs("div", { style: { marginBottom: "12px" }, children: [
|
|
953
1097
|
/* @__PURE__ */ jsx(
|
|
954
1098
|
"div",
|
|
955
1099
|
{
|
|
956
1100
|
style: {
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
marginBottom: "4px"
|
|
1101
|
+
marginBottom: "4px",
|
|
1102
|
+
color: themeVar("labelPrimary"),
|
|
1103
|
+
fontWeight: 500
|
|
961
1104
|
},
|
|
962
|
-
children:
|
|
1105
|
+
children: `Recalled Memories (${recalledCount})`
|
|
963
1106
|
}
|
|
964
1107
|
),
|
|
965
1108
|
memoryItems.length === 0 ? /* @__PURE__ */ jsx(
|
|
966
1109
|
"div",
|
|
967
1110
|
{
|
|
968
1111
|
"data-testid": "empty-memories-message",
|
|
969
|
-
style: {
|
|
970
|
-
padding: "8px 0",
|
|
971
|
-
color: "var(--dsw-text-muted, #94a3b8)",
|
|
972
|
-
fontStyle: "italic",
|
|
973
|
-
fontSize: "11px",
|
|
974
|
-
textAlign: "center"
|
|
975
|
-
},
|
|
1112
|
+
style: { ...mutedStyle, padding: "4px 0" },
|
|
976
1113
|
children: "No memories recalled in this session"
|
|
977
1114
|
}
|
|
978
1115
|
) : /* @__PURE__ */ jsx(
|
|
@@ -996,11 +1133,7 @@ function OpenVikingStatusPopover({
|
|
|
996
1133
|
display: "flex",
|
|
997
1134
|
alignItems: "center",
|
|
998
1135
|
gap: "6px",
|
|
999
|
-
|
|
1000
|
-
borderRadius: "4px",
|
|
1001
|
-
backgroundColor: "rgba(255, 255, 255, 0.04)",
|
|
1002
|
-
border: "1px solid var(--dsw-border-subtle, rgba(255, 255, 255, 0.05))",
|
|
1003
|
-
fontSize: "11px"
|
|
1136
|
+
minWidth: 0
|
|
1004
1137
|
},
|
|
1005
1138
|
children: [
|
|
1006
1139
|
/* @__PURE__ */ jsx(
|
|
@@ -1008,10 +1141,6 @@ function OpenVikingStatusPopover({
|
|
|
1008
1141
|
{
|
|
1009
1142
|
"data-testid": "memory-category-badge",
|
|
1010
1143
|
style: {
|
|
1011
|
-
fontSize: "9px",
|
|
1012
|
-
fontWeight: 600,
|
|
1013
|
-
padding: "1px 4px",
|
|
1014
|
-
borderRadius: "3px",
|
|
1015
1144
|
textTransform: "uppercase",
|
|
1016
1145
|
flexShrink: 0,
|
|
1017
1146
|
...getCategoryBadgeStyle(item.category)
|
|
@@ -1023,21 +1152,7 @@ function OpenVikingStatusPopover({
|
|
|
1023
1152
|
"span",
|
|
1024
1153
|
{
|
|
1025
1154
|
"data-testid": "memory-source-badge",
|
|
1026
|
-
style: {
|
|
1027
|
-
fontSize: "9px",
|
|
1028
|
-
fontWeight: 600,
|
|
1029
|
-
padding: "1px 4px",
|
|
1030
|
-
borderRadius: "3px",
|
|
1031
|
-
textTransform: "uppercase",
|
|
1032
|
-
flexShrink: 0,
|
|
1033
|
-
...item.source === "profile" ? {
|
|
1034
|
-
backgroundColor: "rgba(99, 102, 241, 0.15)",
|
|
1035
|
-
color: "#818cf8"
|
|
1036
|
-
} : {
|
|
1037
|
-
backgroundColor: "rgba(16, 185, 129, 0.15)",
|
|
1038
|
-
color: "var(--dsw-status-success, #34d399)"
|
|
1039
|
-
}
|
|
1040
|
-
},
|
|
1155
|
+
style: { ...mutedStyle, flexShrink: 0 },
|
|
1041
1156
|
children: item.source
|
|
1042
1157
|
}
|
|
1043
1158
|
),
|
|
@@ -1046,12 +1161,10 @@ function OpenVikingStatusPopover({
|
|
|
1046
1161
|
{
|
|
1047
1162
|
"data-testid": "memory-leaf-name",
|
|
1048
1163
|
style: {
|
|
1049
|
-
flex: 1,
|
|
1050
1164
|
overflow: "hidden",
|
|
1051
1165
|
textOverflow: "ellipsis",
|
|
1052
1166
|
whiteSpace: "nowrap",
|
|
1053
|
-
|
|
1054
|
-
color: "var(--dsw-text-default, #f1f5f9)"
|
|
1167
|
+
minWidth: 0
|
|
1055
1168
|
},
|
|
1056
1169
|
children: formatMemoryLeafName(item.uri)
|
|
1057
1170
|
}
|
|
@@ -1067,16 +1180,7 @@ function OpenVikingStatusPopover({
|
|
|
1067
1180
|
"div",
|
|
1068
1181
|
{
|
|
1069
1182
|
"data-testid": "commit-error-message",
|
|
1070
|
-
style: {
|
|
1071
|
-
marginBottom: "8px",
|
|
1072
|
-
padding: "6px 8px",
|
|
1073
|
-
borderRadius: "4px",
|
|
1074
|
-
backgroundColor: "rgba(248, 113, 113, 0.1)",
|
|
1075
|
-
border: "1px solid var(--dsw-status-error, #f87171)",
|
|
1076
|
-
color: "var(--dsw-status-error, #f87171)",
|
|
1077
|
-
fontSize: "11px",
|
|
1078
|
-
wordBreak: "break-word"
|
|
1079
|
-
},
|
|
1183
|
+
style: { marginBottom: "8px", color: themeVar("stateError") },
|
|
1080
1184
|
children: commitError
|
|
1081
1185
|
}
|
|
1082
1186
|
),
|
|
@@ -1085,19 +1189,17 @@ function OpenVikingStatusPopover({
|
|
|
1085
1189
|
{
|
|
1086
1190
|
type: "button",
|
|
1087
1191
|
"data-testid": "commit-now-btn",
|
|
1088
|
-
onClick: () => onCommitNow?.(),
|
|
1192
|
+
onClick: () => void onCommitNow?.(),
|
|
1089
1193
|
disabled: isCommitDisabled,
|
|
1090
1194
|
style: {
|
|
1091
1195
|
width: "100%",
|
|
1092
|
-
padding: "
|
|
1093
|
-
borderRadius: "
|
|
1094
|
-
border:
|
|
1095
|
-
|
|
1096
|
-
color: isCommitDisabled ? "
|
|
1097
|
-
cursor: isCommitDisabled ? "
|
|
1098
|
-
|
|
1099
|
-
fontSize: "12px",
|
|
1100
|
-
transition: "all 0.15s ease",
|
|
1196
|
+
padding: "6px 10px",
|
|
1197
|
+
borderRadius: "8px",
|
|
1198
|
+
border: `.5px solid ${themeVar("hairline")}`,
|
|
1199
|
+
background: isCommitDisabled ? "transparent" : themeVar("hoverBackground"),
|
|
1200
|
+
color: isCommitDisabled ? themeVar("labelTertiary") : themeVar("labelPrimary"),
|
|
1201
|
+
cursor: isCommitDisabled ? "default" : "pointer",
|
|
1202
|
+
font: "inherit",
|
|
1101
1203
|
display: "flex",
|
|
1102
1204
|
alignItems: "center",
|
|
1103
1205
|
justifyContent: "center",
|
|
@@ -1107,12 +1209,13 @@ function OpenVikingStatusPopover({
|
|
|
1107
1209
|
/* @__PURE__ */ jsx(
|
|
1108
1210
|
"span",
|
|
1109
1211
|
{
|
|
1212
|
+
"aria-hidden": "true",
|
|
1110
1213
|
style: {
|
|
1111
1214
|
display: "inline-block",
|
|
1112
1215
|
width: "10px",
|
|
1113
1216
|
height: "10px",
|
|
1114
1217
|
borderRadius: "50%",
|
|
1115
|
-
border:
|
|
1218
|
+
border: `2px solid ${themeVar("stateWarning")}`,
|
|
1116
1219
|
borderTopColor: "transparent",
|
|
1117
1220
|
animation: "ov-spin 1s linear infinite"
|
|
1118
1221
|
}
|
|
@@ -1144,11 +1247,15 @@ function formatTooltipTitle({
|
|
|
1144
1247
|
isOnline,
|
|
1145
1248
|
isCommitting = false,
|
|
1146
1249
|
recalledCount,
|
|
1147
|
-
pendingTokens
|
|
1250
|
+
pendingTokens,
|
|
1251
|
+
sessionUnreadable = false
|
|
1148
1252
|
}) {
|
|
1149
1253
|
if (!isOnline) {
|
|
1150
1254
|
return "OpenViking: Offline";
|
|
1151
1255
|
}
|
|
1256
|
+
if (sessionUnreadable) {
|
|
1257
|
+
return "OpenViking: session unreadable \u2014 the daemon requires an API key";
|
|
1258
|
+
}
|
|
1152
1259
|
const countLabel = `${recalledCount} recalled`;
|
|
1153
1260
|
const tokenLabel = `${(pendingTokens || 0).toLocaleString()} pending tokens`;
|
|
1154
1261
|
if (isCommitting) {
|
|
@@ -1156,36 +1263,69 @@ function formatTooltipTitle({
|
|
|
1156
1263
|
}
|
|
1157
1264
|
return `OpenViking: Online (${countLabel}, ${tokenLabel})`;
|
|
1158
1265
|
}
|
|
1159
|
-
function getStatusIndicatorColor(isOnline, isCommitting = false) {
|
|
1266
|
+
function getStatusIndicatorColor(isOnline, isCommitting = false, sessionUnreadable = false) {
|
|
1160
1267
|
if (!isOnline) {
|
|
1161
|
-
return "
|
|
1268
|
+
return themeVar("stateError");
|
|
1162
1269
|
}
|
|
1163
|
-
if (isCommitting) {
|
|
1164
|
-
return "
|
|
1270
|
+
if (isCommitting || sessionUnreadable) {
|
|
1271
|
+
return themeVar("stateWarning");
|
|
1165
1272
|
}
|
|
1166
|
-
return "
|
|
1273
|
+
return themeVar("stateSuccess");
|
|
1167
1274
|
}
|
|
1168
|
-
function
|
|
1169
|
-
if (
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1275
|
+
function chatNodesToText(nodes) {
|
|
1276
|
+
if (!nodes) return "";
|
|
1277
|
+
const source = Array.isArray(nodes) ? nodes : typeof nodes === "object" ? Object.values(nodes) : [];
|
|
1278
|
+
const parts = [];
|
|
1279
|
+
const visit = (value, depth = 0) => {
|
|
1280
|
+
if (depth > 4 || value === null || value === void 0) return;
|
|
1281
|
+
if (typeof value === "string") {
|
|
1282
|
+
parts.push(value);
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
1285
|
+
if (Array.isArray(value)) {
|
|
1286
|
+
for (const item of value) visit(item, depth + 1);
|
|
1287
|
+
return;
|
|
1288
|
+
}
|
|
1289
|
+
if (typeof value === "object") {
|
|
1290
|
+
const record = value;
|
|
1291
|
+
for (const key of ["content", "text", "data", "body"]) {
|
|
1292
|
+
if (key in record) visit(record[key], depth + 1);
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
};
|
|
1296
|
+
for (const node of source) visit(node);
|
|
1297
|
+
return parts.join("\n");
|
|
1173
1298
|
}
|
|
1174
|
-
function
|
|
1175
|
-
|
|
1176
|
-
|
|
1299
|
+
function OpenVikingStatusChip(props) {
|
|
1300
|
+
const { useChat, ...rest } = props;
|
|
1301
|
+
if (useChat && rest.contextText === void 0 && rest.messages === void 0) {
|
|
1302
|
+
return /* @__PURE__ */ jsx2(ChatReadBoundary, { fallback: /* @__PURE__ */ jsx2(StatusChipView, { ...rest }), children: /* @__PURE__ */ jsx2(ChatBackedStatusChip, { useChat, ...rest }) });
|
|
1177
1303
|
}
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1304
|
+
return /* @__PURE__ */ jsx2(StatusChipView, { ...rest });
|
|
1305
|
+
}
|
|
1306
|
+
var ChatReadBoundary = class extends React2.Component {
|
|
1307
|
+
state = { failed: false };
|
|
1308
|
+
static getDerivedStateFromError() {
|
|
1309
|
+
return { failed: true };
|
|
1182
1310
|
}
|
|
1183
|
-
|
|
1184
|
-
return
|
|
1311
|
+
render() {
|
|
1312
|
+
return this.state.failed ? this.props.fallback : this.props.children;
|
|
1185
1313
|
}
|
|
1186
|
-
|
|
1314
|
+
};
|
|
1315
|
+
function ChatBackedStatusChip({
|
|
1316
|
+
useChat,
|
|
1317
|
+
...rest
|
|
1318
|
+
}) {
|
|
1319
|
+
const nodes = useChat((snapshot) => {
|
|
1320
|
+
try {
|
|
1321
|
+
return snapshot?.legacy?.nodes !== void 0 ? snapshot.legacy.nodes : snapshot?.nodes;
|
|
1322
|
+
} catch {
|
|
1323
|
+
return void 0;
|
|
1324
|
+
}
|
|
1325
|
+
});
|
|
1326
|
+
return /* @__PURE__ */ jsx2(StatusChipView, { ...rest, messages: nodes });
|
|
1187
1327
|
}
|
|
1188
|
-
function
|
|
1328
|
+
function StatusChipView({
|
|
1189
1329
|
sessionId,
|
|
1190
1330
|
messages,
|
|
1191
1331
|
contextText,
|
|
@@ -1194,32 +1334,42 @@ function OpenVikingStatusChip({
|
|
|
1194
1334
|
className,
|
|
1195
1335
|
initialHealth,
|
|
1196
1336
|
initialSessionData,
|
|
1337
|
+
initialSessionRead,
|
|
1197
1338
|
initialOpen = false
|
|
1198
1339
|
}) {
|
|
1199
1340
|
const [health, setHealth] = useState2(
|
|
1200
1341
|
initialHealth ?? null
|
|
1201
1342
|
);
|
|
1202
|
-
const [
|
|
1203
|
-
|
|
1343
|
+
const [sessionRead, setSessionRead] = useState2(
|
|
1344
|
+
initialSessionRead ?? (initialSessionData ? { status: "ok", session: initialSessionData } : null)
|
|
1204
1345
|
);
|
|
1205
1346
|
const [isOpen, setIsOpen] = useState2(initialOpen);
|
|
1206
1347
|
const [isCommitting, setIsCommitting] = useState2(false);
|
|
1207
1348
|
const [commitError, setCommitError] = useState2(null);
|
|
1349
|
+
const [isHovered, setIsHovered] = useState2(false);
|
|
1350
|
+
const [statsHost, setStatsHost] = useState2(null);
|
|
1208
1351
|
const popoverRef = useRef2(null);
|
|
1209
1352
|
const apiClient = client ?? defaultOpenVikingClient;
|
|
1210
|
-
|
|
1211
|
-
if (
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
if (contextText && messages) {
|
|
1216
|
-
return [contextText, ...messages];
|
|
1353
|
+
useEffect2(() => {
|
|
1354
|
+
if (typeof document === "undefined") return;
|
|
1355
|
+
function findHost() {
|
|
1356
|
+
const el = document.querySelector("[data-composer-stats]");
|
|
1357
|
+
setStatsHost((prev) => prev !== el ? el : prev);
|
|
1217
1358
|
}
|
|
1218
|
-
|
|
1219
|
-
|
|
1359
|
+
findHost();
|
|
1360
|
+
const observer = new MutationObserver(() => {
|
|
1361
|
+
findHost();
|
|
1362
|
+
});
|
|
1363
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
1364
|
+
return () => observer.disconnect();
|
|
1365
|
+
}, []);
|
|
1366
|
+
const conversationText = useMemo(() => {
|
|
1367
|
+
if (typeof contextText === "string") return contextText;
|
|
1368
|
+
return chatNodesToText(messages);
|
|
1369
|
+
}, [contextText, messages]);
|
|
1220
1370
|
const recalledResult = useMemo(
|
|
1221
|
-
() => parseRecalledMemories(
|
|
1222
|
-
[
|
|
1371
|
+
() => parseRecalledMemories(conversationText),
|
|
1372
|
+
[conversationText]
|
|
1223
1373
|
);
|
|
1224
1374
|
const fetchStatus = useCallback2(async () => {
|
|
1225
1375
|
try {
|
|
@@ -1228,8 +1378,7 @@ function OpenVikingStatusChip({
|
|
|
1228
1378
|
if (!healthRes.ok) {
|
|
1229
1379
|
return;
|
|
1230
1380
|
}
|
|
1231
|
-
|
|
1232
|
-
setSessionData(session);
|
|
1381
|
+
setSessionRead(await apiClient.readSession(sessionId));
|
|
1233
1382
|
} catch {
|
|
1234
1383
|
setHealth({ ok: false });
|
|
1235
1384
|
}
|
|
@@ -1282,26 +1431,29 @@ function OpenVikingStatusChip({
|
|
|
1282
1431
|
}
|
|
1283
1432
|
};
|
|
1284
1433
|
const isOnline = health?.ok === true;
|
|
1434
|
+
const sessionData = sessionRead?.status === "ok" ? sessionRead.session : null;
|
|
1435
|
+
const sessionUnreadable = isOnline && sessionRead !== null && sessionRead.status !== "ok";
|
|
1285
1436
|
const pendingTokens = sessionData?.pending_tokens ?? 0;
|
|
1286
|
-
const pendingTokensK = Math.round(pendingTokens / 1e3);
|
|
1287
1437
|
const recalledCount = recalledResult.recalledCount;
|
|
1288
|
-
const statusColor = getStatusIndicatorColor(
|
|
1289
|
-
|
|
1438
|
+
const statusColor = getStatusIndicatorColor(
|
|
1439
|
+
isOnline,
|
|
1440
|
+
isCommitting,
|
|
1441
|
+
sessionUnreadable
|
|
1442
|
+
);
|
|
1290
1443
|
const tooltipTitle = formatTooltipTitle({
|
|
1291
1444
|
isOnline,
|
|
1292
1445
|
isCommitting,
|
|
1293
1446
|
recalledCount,
|
|
1294
|
-
pendingTokens
|
|
1447
|
+
pendingTokens,
|
|
1448
|
+
sessionUnreadable
|
|
1295
1449
|
});
|
|
1296
|
-
|
|
1297
|
-
|
|
1450
|
+
const label = !isOnline ? "OV offline" : sessionUnreadable ? `OV: ${recalledCount} rec \xB7 no access` : `OV: ${recalledCount} rec \xB7 ${Math.round(pendingTokens / 1e3)}k pend`;
|
|
1451
|
+
const chipElement = /* @__PURE__ */ jsxs2(
|
|
1452
|
+
"span",
|
|
1298
1453
|
{
|
|
1299
1454
|
className,
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
display: "inline-flex",
|
|
1303
|
-
alignItems: "center"
|
|
1304
|
-
},
|
|
1455
|
+
"data-openviking-status": "true",
|
|
1456
|
+
style: { minWidth: 0, display: "inline-flex", position: "relative" },
|
|
1305
1457
|
ref: popoverRef,
|
|
1306
1458
|
children: [
|
|
1307
1459
|
/* @__PURE__ */ jsxs2(
|
|
@@ -1309,23 +1461,27 @@ function OpenVikingStatusChip({
|
|
|
1309
1461
|
{
|
|
1310
1462
|
type: "button",
|
|
1311
1463
|
onClick: () => setIsOpen(!isOpen),
|
|
1464
|
+
onMouseEnter: () => setIsHovered(true),
|
|
1465
|
+
onMouseLeave: () => setIsHovered(false),
|
|
1312
1466
|
"aria-expanded": isOpen,
|
|
1313
1467
|
"aria-haspopup": "dialog",
|
|
1314
1468
|
style: {
|
|
1315
|
-
|
|
1469
|
+
boxSizing: "border-box",
|
|
1470
|
+
maxWidth: "100%",
|
|
1471
|
+
color: isHovered ? themeVar("labelSecondary") : themeVar("labelTertiary"),
|
|
1472
|
+
fontFamily: "var(--dsw-font-family, system-ui)",
|
|
1473
|
+
fontSize: "var(--dsh-content-font-size-secondary, 13px)",
|
|
1474
|
+
lineHeight: "calc(20px + var(--dsh-content-font-delta-secondary, 0px))",
|
|
1475
|
+
fontVariantNumeric: "tabular-nums",
|
|
1476
|
+
whiteSpace: "nowrap",
|
|
1477
|
+
background: isHovered ? themeVar("hoverBackground") : "transparent",
|
|
1478
|
+
border: "none",
|
|
1479
|
+
borderRadius: "24px",
|
|
1316
1480
|
alignItems: "center",
|
|
1317
1481
|
gap: "6px",
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
fontFamily: "var(--dsw-font-mono, monospace)",
|
|
1322
|
-
borderRadius: "6px",
|
|
1323
|
-
background: "var(--dsw-surface-base, rgba(255, 255, 255, 0.05))",
|
|
1324
|
-
border: "1px solid var(--dsw-border-subtle, rgba(255, 255, 255, 0.1))",
|
|
1325
|
-
color: "var(--dsw-text-muted, #94a3b8)",
|
|
1326
|
-
cursor: "pointer",
|
|
1327
|
-
transition: "all 0.15s ease",
|
|
1328
|
-
userSelect: "none"
|
|
1482
|
+
padding: "1px 8px",
|
|
1483
|
+
display: "inline-flex",
|
|
1484
|
+
cursor: "pointer"
|
|
1329
1485
|
},
|
|
1330
1486
|
title: tooltipTitle,
|
|
1331
1487
|
"aria-label": tooltipTitle,
|
|
@@ -1334,25 +1490,17 @@ function OpenVikingStatusChip({
|
|
|
1334
1490
|
"span",
|
|
1335
1491
|
{
|
|
1336
1492
|
"data-testid": "status-dot",
|
|
1493
|
+
"aria-hidden": "true",
|
|
1337
1494
|
style: {
|
|
1338
|
-
width: "
|
|
1339
|
-
height: "
|
|
1495
|
+
width: "6px",
|
|
1496
|
+
height: "6px",
|
|
1340
1497
|
borderRadius: "50%",
|
|
1341
|
-
|
|
1342
|
-
boxShadow: statusGlow,
|
|
1498
|
+
background: statusColor,
|
|
1343
1499
|
flexShrink: 0
|
|
1344
1500
|
}
|
|
1345
1501
|
}
|
|
1346
1502
|
),
|
|
1347
|
-
/* @__PURE__ */ jsx2(
|
|
1348
|
-
"span",
|
|
1349
|
-
{
|
|
1350
|
-
style: { fontWeight: 600, color: "var(--dsw-text-default, #e2e8f0)" },
|
|
1351
|
-
children: isOnline ? "OV:" : "OV"
|
|
1352
|
-
}
|
|
1353
|
-
),
|
|
1354
|
-
" ",
|
|
1355
|
-
/* @__PURE__ */ jsx2("span", { children: isOnline ? `${recalledCount} rec \xB7 ${pendingTokensK}k pend` : "offline" })
|
|
1503
|
+
/* @__PURE__ */ jsx2("span", { style: { textOverflow: "ellipsis", minWidth: 0 }, children: label })
|
|
1356
1504
|
]
|
|
1357
1505
|
}
|
|
1358
1506
|
),
|
|
@@ -1362,6 +1510,7 @@ function OpenVikingStatusChip({
|
|
|
1362
1510
|
sessionId,
|
|
1363
1511
|
health,
|
|
1364
1512
|
sessionData,
|
|
1513
|
+
sessionRead,
|
|
1365
1514
|
recalledResult,
|
|
1366
1515
|
endpoint: apiClient.endpoint,
|
|
1367
1516
|
isCommitting,
|
|
@@ -1373,6 +1522,572 @@ function OpenVikingStatusChip({
|
|
|
1373
1522
|
]
|
|
1374
1523
|
}
|
|
1375
1524
|
);
|
|
1525
|
+
if (statsHost && typeof document !== "undefined") {
|
|
1526
|
+
return ReactDOM.createPortal(chipElement, statsHost);
|
|
1527
|
+
}
|
|
1528
|
+
return /* @__PURE__ */ jsx2(
|
|
1529
|
+
"div",
|
|
1530
|
+
{
|
|
1531
|
+
style: {
|
|
1532
|
+
maxWidth: "var(--dsh-chat-content-width, 748px)",
|
|
1533
|
+
boxSizing: "border-box",
|
|
1534
|
+
width: "100%",
|
|
1535
|
+
padding: "4px calc(var(--dsh-composer-side-clearance, 0px) + 16px) 0px",
|
|
1536
|
+
fontSize: "var(--dsh-content-font-size-secondary, 13px)",
|
|
1537
|
+
lineHeight: "calc(20px + var(--dsh-content-font-delta-secondary, 0px))",
|
|
1538
|
+
justifyContent: "center",
|
|
1539
|
+
gap: "12px",
|
|
1540
|
+
margin: "0 auto",
|
|
1541
|
+
display: "flex"
|
|
1542
|
+
},
|
|
1543
|
+
children: chipElement
|
|
1544
|
+
}
|
|
1545
|
+
);
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
// src/client/OpenVikingSettingsSection.tsx
|
|
1549
|
+
import { useState as useState3, useEffect as useEffect3 } from "react";
|
|
1550
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1551
|
+
var API_CONFIG = "/openviking-status/api/config";
|
|
1552
|
+
var API_TEST = "/openviking-status/api/test-connection";
|
|
1553
|
+
var SOURCE_LABELS = {
|
|
1554
|
+
ovcli: "Auto-detected from ~/.openviking/ovcli.conf",
|
|
1555
|
+
env: "Auto-detected from environment variables",
|
|
1556
|
+
ov: "Auto-detected from ~/.openviking/ov.conf",
|
|
1557
|
+
settings: "Custom override in DSH settings.yaml",
|
|
1558
|
+
default: "Default local configuration"
|
|
1559
|
+
};
|
|
1560
|
+
function OpenVikingSettingsSection({
|
|
1561
|
+
initialConfig,
|
|
1562
|
+
onConfigSaved,
|
|
1563
|
+
className,
|
|
1564
|
+
style
|
|
1565
|
+
}) {
|
|
1566
|
+
const [endpoint, setEndpoint] = useState3(
|
|
1567
|
+
initialConfig?.endpoint || "http://127.0.0.1:1933"
|
|
1568
|
+
);
|
|
1569
|
+
const [apiKey, setApiKey] = useState3("");
|
|
1570
|
+
const [showKey, setShowKey] = useState3(false);
|
|
1571
|
+
const [source, setSource] = useState3(
|
|
1572
|
+
initialConfig?.source || "default"
|
|
1573
|
+
);
|
|
1574
|
+
const [hasStoredKey, setHasStoredKey] = useState3(
|
|
1575
|
+
initialConfig?.hasApiKey || false
|
|
1576
|
+
);
|
|
1577
|
+
const [loading, setLoading] = useState3(!initialConfig);
|
|
1578
|
+
const [testing, setTesting] = useState3(false);
|
|
1579
|
+
const [saving, setSaving] = useState3(false);
|
|
1580
|
+
const [testResult, setTestResult] = useState3(null);
|
|
1581
|
+
const [flash, setFlash] = useState3(null);
|
|
1582
|
+
useEffect3(() => {
|
|
1583
|
+
if (initialConfig) return;
|
|
1584
|
+
let active = true;
|
|
1585
|
+
async function fetchConfig() {
|
|
1586
|
+
try {
|
|
1587
|
+
setLoading(true);
|
|
1588
|
+
const res = await fetch(API_CONFIG, { cache: "no-store" });
|
|
1589
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
1590
|
+
const data = await res.json();
|
|
1591
|
+
if (!active) return;
|
|
1592
|
+
const newEp = data.endpoint || "http://127.0.0.1:1933";
|
|
1593
|
+
setEndpoint(newEp);
|
|
1594
|
+
setSource(data.source || "default");
|
|
1595
|
+
setHasStoredKey(data.hasApiKey);
|
|
1596
|
+
defaultOpenVikingClient.clearResolvedSessions();
|
|
1597
|
+
} catch {
|
|
1598
|
+
} finally {
|
|
1599
|
+
if (active) setLoading(false);
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
void fetchConfig();
|
|
1603
|
+
return () => {
|
|
1604
|
+
active = false;
|
|
1605
|
+
};
|
|
1606
|
+
}, [initialConfig]);
|
|
1607
|
+
async function handleTestConnection() {
|
|
1608
|
+
setTesting(true);
|
|
1609
|
+
setTestResult(null);
|
|
1610
|
+
setFlash(null);
|
|
1611
|
+
try {
|
|
1612
|
+
const res = await fetch(API_TEST, {
|
|
1613
|
+
method: "POST",
|
|
1614
|
+
headers: { "Content-Type": "application/json" },
|
|
1615
|
+
body: JSON.stringify({
|
|
1616
|
+
endpoint: endpoint.trim(),
|
|
1617
|
+
apiKey: apiKey.trim() || void 0
|
|
1618
|
+
})
|
|
1619
|
+
});
|
|
1620
|
+
const data = await res.json();
|
|
1621
|
+
setTestResult(data);
|
|
1622
|
+
} catch (err) {
|
|
1623
|
+
setTestResult({
|
|
1624
|
+
ok: false,
|
|
1625
|
+
authenticated: false,
|
|
1626
|
+
error: String(err instanceof Error ? err.message : err)
|
|
1627
|
+
});
|
|
1628
|
+
} finally {
|
|
1629
|
+
setTesting(false);
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
async function handleSave() {
|
|
1633
|
+
setSaving(true);
|
|
1634
|
+
setFlash(null);
|
|
1635
|
+
try {
|
|
1636
|
+
const res = await fetch(API_CONFIG, {
|
|
1637
|
+
method: "POST",
|
|
1638
|
+
headers: { "Content-Type": "application/json" },
|
|
1639
|
+
body: JSON.stringify({
|
|
1640
|
+
endpoint: endpoint.trim(),
|
|
1641
|
+
apiKey: apiKey.trim() || void 0
|
|
1642
|
+
})
|
|
1643
|
+
});
|
|
1644
|
+
const data = await res.json();
|
|
1645
|
+
if (!res.ok || data.error) {
|
|
1646
|
+
throw new Error(data.error || `HTTP ${res.status}`);
|
|
1647
|
+
}
|
|
1648
|
+
setFlash({ kind: "ok", message: "Settings saved successfully" });
|
|
1649
|
+
setSource("settings");
|
|
1650
|
+
defaultOpenVikingClient.clearResolvedSessions();
|
|
1651
|
+
if (apiKey.trim()) {
|
|
1652
|
+
setHasStoredKey(true);
|
|
1653
|
+
setApiKey("");
|
|
1654
|
+
}
|
|
1655
|
+
onConfigSaved?.(
|
|
1656
|
+
data.config || {
|
|
1657
|
+
endpoint,
|
|
1658
|
+
hasApiKey: hasStoredKey || Boolean(apiKey.trim()),
|
|
1659
|
+
source: "settings"
|
|
1660
|
+
}
|
|
1661
|
+
);
|
|
1662
|
+
} catch (err) {
|
|
1663
|
+
setFlash({
|
|
1664
|
+
kind: "err",
|
|
1665
|
+
message: `Failed to save: ${err instanceof Error ? err.message : String(err)}`
|
|
1666
|
+
});
|
|
1667
|
+
} finally {
|
|
1668
|
+
setSaving(false);
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
async function handleReset() {
|
|
1672
|
+
setSaving(true);
|
|
1673
|
+
setFlash(null);
|
|
1674
|
+
setTestResult(null);
|
|
1675
|
+
try {
|
|
1676
|
+
const res = await fetch(API_CONFIG, {
|
|
1677
|
+
method: "POST",
|
|
1678
|
+
headers: { "Content-Type": "application/json" },
|
|
1679
|
+
body: JSON.stringify({ reset: true })
|
|
1680
|
+
});
|
|
1681
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
1682
|
+
const cfgRes = await fetch(API_CONFIG, { cache: "no-store" });
|
|
1683
|
+
if (cfgRes.ok) {
|
|
1684
|
+
const data = await cfgRes.json();
|
|
1685
|
+
const newEp = data.endpoint || "http://127.0.0.1:1933";
|
|
1686
|
+
setEndpoint(newEp);
|
|
1687
|
+
setSource(data.source || "default");
|
|
1688
|
+
setHasStoredKey(data.hasApiKey);
|
|
1689
|
+
setApiKey("");
|
|
1690
|
+
defaultOpenVikingClient.clearResolvedSessions();
|
|
1691
|
+
setFlash({
|
|
1692
|
+
kind: "ok",
|
|
1693
|
+
message: "Reset to auto-detected local settings"
|
|
1694
|
+
});
|
|
1695
|
+
onConfigSaved?.(data);
|
|
1696
|
+
}
|
|
1697
|
+
} catch (err) {
|
|
1698
|
+
setFlash({
|
|
1699
|
+
kind: "err",
|
|
1700
|
+
message: `Failed to reset: ${err instanceof Error ? err.message : String(err)}`
|
|
1701
|
+
});
|
|
1702
|
+
} finally {
|
|
1703
|
+
setSaving(false);
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
const sourceBadgeText = SOURCE_LABELS[source] || SOURCE_LABELS["default"];
|
|
1707
|
+
return /* @__PURE__ */ jsxs3(
|
|
1708
|
+
"div",
|
|
1709
|
+
{
|
|
1710
|
+
className: `ov-settings-root ${className || ""}`,
|
|
1711
|
+
style: {
|
|
1712
|
+
display: "flex",
|
|
1713
|
+
flexDirection: "column",
|
|
1714
|
+
gap: 20,
|
|
1715
|
+
maxWidth: 720,
|
|
1716
|
+
padding: "24px 28px",
|
|
1717
|
+
color: themeVar("labelPrimary"),
|
|
1718
|
+
fontSize: 14,
|
|
1719
|
+
lineHeight: 1.6,
|
|
1720
|
+
...style
|
|
1721
|
+
},
|
|
1722
|
+
children: [
|
|
1723
|
+
/* @__PURE__ */ jsxs3("div", { children: [
|
|
1724
|
+
/* @__PURE__ */ jsxs3(
|
|
1725
|
+
"div",
|
|
1726
|
+
{
|
|
1727
|
+
style: {
|
|
1728
|
+
display: "flex",
|
|
1729
|
+
alignItems: "baseline",
|
|
1730
|
+
gap: 12,
|
|
1731
|
+
marginBottom: 6
|
|
1732
|
+
},
|
|
1733
|
+
children: [
|
|
1734
|
+
/* @__PURE__ */ jsx3(
|
|
1735
|
+
"h2",
|
|
1736
|
+
{
|
|
1737
|
+
style: {
|
|
1738
|
+
fontSize: 20,
|
|
1739
|
+
fontWeight: 600,
|
|
1740
|
+
margin: 0,
|
|
1741
|
+
color: themeVar("labelPrimary")
|
|
1742
|
+
},
|
|
1743
|
+
children: "OpenViking Status"
|
|
1744
|
+
}
|
|
1745
|
+
),
|
|
1746
|
+
/* @__PURE__ */ jsx3(
|
|
1747
|
+
"span",
|
|
1748
|
+
{
|
|
1749
|
+
style: {
|
|
1750
|
+
fontSize: 12,
|
|
1751
|
+
fontWeight: 500,
|
|
1752
|
+
padding: "2px 8px",
|
|
1753
|
+
borderRadius: 6,
|
|
1754
|
+
background: themeVar("insetSurface"),
|
|
1755
|
+
border: `1px solid ${themeVar("hairline")}`,
|
|
1756
|
+
color: themeVar("labelSecondary")
|
|
1757
|
+
},
|
|
1758
|
+
children: sourceBadgeText
|
|
1759
|
+
}
|
|
1760
|
+
)
|
|
1761
|
+
]
|
|
1762
|
+
}
|
|
1763
|
+
),
|
|
1764
|
+
/* @__PURE__ */ jsx3(
|
|
1765
|
+
"p",
|
|
1766
|
+
{
|
|
1767
|
+
style: { margin: 0, color: themeVar("labelSecondary"), fontSize: 13 },
|
|
1768
|
+
children: "Configure connection credentials for monitoring OpenViking persistent memory and session status."
|
|
1769
|
+
}
|
|
1770
|
+
)
|
|
1771
|
+
] }),
|
|
1772
|
+
/* @__PURE__ */ jsxs3(
|
|
1773
|
+
"div",
|
|
1774
|
+
{
|
|
1775
|
+
style: {
|
|
1776
|
+
border: `1px solid ${themeVar("hairline")}`,
|
|
1777
|
+
borderRadius: 12,
|
|
1778
|
+
padding: 20,
|
|
1779
|
+
background: themeVar("insetSurface"),
|
|
1780
|
+
display: "flex",
|
|
1781
|
+
flexDirection: "column",
|
|
1782
|
+
gap: 16
|
|
1783
|
+
},
|
|
1784
|
+
children: [
|
|
1785
|
+
/* @__PURE__ */ jsxs3("div", { children: [
|
|
1786
|
+
/* @__PURE__ */ jsx3(
|
|
1787
|
+
"label",
|
|
1788
|
+
{
|
|
1789
|
+
style: {
|
|
1790
|
+
display: "block",
|
|
1791
|
+
fontSize: 13,
|
|
1792
|
+
fontWeight: 600,
|
|
1793
|
+
marginBottom: 6,
|
|
1794
|
+
color: themeVar("labelPrimary")
|
|
1795
|
+
},
|
|
1796
|
+
children: "Daemon Endpoint"
|
|
1797
|
+
}
|
|
1798
|
+
),
|
|
1799
|
+
/* @__PURE__ */ jsx3(
|
|
1800
|
+
"input",
|
|
1801
|
+
{
|
|
1802
|
+
type: "text",
|
|
1803
|
+
value: endpoint,
|
|
1804
|
+
onChange: (e) => setEndpoint(e.target.value),
|
|
1805
|
+
placeholder: "http://127.0.0.1:1933",
|
|
1806
|
+
style: {
|
|
1807
|
+
width: "100%",
|
|
1808
|
+
boxSizing: "border-box",
|
|
1809
|
+
padding: "9px 12px",
|
|
1810
|
+
fontSize: 14,
|
|
1811
|
+
fontFamily: themeVar("fontMono"),
|
|
1812
|
+
borderRadius: 8,
|
|
1813
|
+
border: `1px solid ${themeVar("hairline")}`,
|
|
1814
|
+
background: themeVar("panelSurface"),
|
|
1815
|
+
color: themeVar("labelPrimary"),
|
|
1816
|
+
outline: "none"
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
),
|
|
1820
|
+
/* @__PURE__ */ jsx3(
|
|
1821
|
+
"span",
|
|
1822
|
+
{
|
|
1823
|
+
style: {
|
|
1824
|
+
fontSize: 12,
|
|
1825
|
+
color: themeVar("labelTertiary"),
|
|
1826
|
+
marginTop: 4,
|
|
1827
|
+
display: "block"
|
|
1828
|
+
},
|
|
1829
|
+
children: "The URL of the local or remote OpenViking HTTP server. Resolved from the DSH host."
|
|
1830
|
+
}
|
|
1831
|
+
)
|
|
1832
|
+
] }),
|
|
1833
|
+
/* @__PURE__ */ jsxs3("div", { children: [
|
|
1834
|
+
/* @__PURE__ */ jsxs3(
|
|
1835
|
+
"div",
|
|
1836
|
+
{
|
|
1837
|
+
style: {
|
|
1838
|
+
display: "flex",
|
|
1839
|
+
justifyContent: "space-between",
|
|
1840
|
+
alignItems: "center",
|
|
1841
|
+
marginBottom: 6
|
|
1842
|
+
},
|
|
1843
|
+
children: [
|
|
1844
|
+
/* @__PURE__ */ jsx3(
|
|
1845
|
+
"label",
|
|
1846
|
+
{
|
|
1847
|
+
style: {
|
|
1848
|
+
fontSize: 13,
|
|
1849
|
+
fontWeight: 600,
|
|
1850
|
+
color: themeVar("labelPrimary")
|
|
1851
|
+
},
|
|
1852
|
+
children: "API Token (Authentication)"
|
|
1853
|
+
}
|
|
1854
|
+
),
|
|
1855
|
+
hasStoredKey && !apiKey && /* @__PURE__ */ jsx3(
|
|
1856
|
+
"span",
|
|
1857
|
+
{
|
|
1858
|
+
style: {
|
|
1859
|
+
fontSize: 12,
|
|
1860
|
+
color: themeVar("stateSuccess"),
|
|
1861
|
+
fontWeight: 500
|
|
1862
|
+
},
|
|
1863
|
+
children: "\u25CF Active token configured"
|
|
1864
|
+
}
|
|
1865
|
+
)
|
|
1866
|
+
]
|
|
1867
|
+
}
|
|
1868
|
+
),
|
|
1869
|
+
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: 8 }, children: [
|
|
1870
|
+
/* @__PURE__ */ jsx3(
|
|
1871
|
+
"input",
|
|
1872
|
+
{
|
|
1873
|
+
type: showKey ? "text" : "password",
|
|
1874
|
+
value: apiKey,
|
|
1875
|
+
onChange: (e) => setApiKey(e.target.value),
|
|
1876
|
+
placeholder: hasStoredKey ? "(Token stored \u2014 leave blank to keep unchanged)" : "Optional or required if daemon uses auth_mode: api_key",
|
|
1877
|
+
style: {
|
|
1878
|
+
flex: 1,
|
|
1879
|
+
padding: "9px 12px",
|
|
1880
|
+
fontSize: 14,
|
|
1881
|
+
fontFamily: themeVar("fontMono"),
|
|
1882
|
+
borderRadius: 8,
|
|
1883
|
+
border: `1px solid ${themeVar("hairline")}`,
|
|
1884
|
+
background: themeVar("panelSurface"),
|
|
1885
|
+
color: themeVar("labelPrimary"),
|
|
1886
|
+
outline: "none"
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
),
|
|
1890
|
+
/* @__PURE__ */ jsx3(
|
|
1891
|
+
"button",
|
|
1892
|
+
{
|
|
1893
|
+
type: "button",
|
|
1894
|
+
onClick: () => setShowKey((v) => !v),
|
|
1895
|
+
style: {
|
|
1896
|
+
padding: "0 14px",
|
|
1897
|
+
fontSize: 13,
|
|
1898
|
+
fontWeight: 500,
|
|
1899
|
+
borderRadius: 8,
|
|
1900
|
+
border: `1px solid ${themeVar("hairline")}`,
|
|
1901
|
+
background: themeVar("panelSurface"),
|
|
1902
|
+
color: themeVar("labelSecondary"),
|
|
1903
|
+
cursor: "pointer"
|
|
1904
|
+
},
|
|
1905
|
+
children: showKey ? "Hide" : "Show"
|
|
1906
|
+
}
|
|
1907
|
+
)
|
|
1908
|
+
] }),
|
|
1909
|
+
/* @__PURE__ */ jsx3(
|
|
1910
|
+
"span",
|
|
1911
|
+
{
|
|
1912
|
+
style: {
|
|
1913
|
+
fontSize: 12,
|
|
1914
|
+
color: themeVar("labelTertiary"),
|
|
1915
|
+
marginTop: 4,
|
|
1916
|
+
display: "block"
|
|
1917
|
+
},
|
|
1918
|
+
children: "Required when the daemon runs with auth_mode: api_key. Local tokens are typically found in ~/.openviking/ovcli.conf."
|
|
1919
|
+
}
|
|
1920
|
+
)
|
|
1921
|
+
] }),
|
|
1922
|
+
testResult && /* @__PURE__ */ jsxs3(
|
|
1923
|
+
"div",
|
|
1924
|
+
{
|
|
1925
|
+
style: {
|
|
1926
|
+
padding: "10px 14px",
|
|
1927
|
+
borderRadius: 8,
|
|
1928
|
+
fontSize: 13,
|
|
1929
|
+
display: "flex",
|
|
1930
|
+
alignItems: "center",
|
|
1931
|
+
gap: 8,
|
|
1932
|
+
border: `1px solid ${testResult.ok && testResult.authenticated ? themeVar("stateSuccess") : themeVar("stateError")}`,
|
|
1933
|
+
background: themeVar("panelSurface"),
|
|
1934
|
+
color: testResult.ok && testResult.authenticated ? themeVar("stateSuccess") : themeVar("stateError")
|
|
1935
|
+
},
|
|
1936
|
+
children: [
|
|
1937
|
+
/* @__PURE__ */ jsx3("span", { children: testResult.ok && testResult.authenticated ? "\u25CF" : "\u2715" }),
|
|
1938
|
+
/* @__PURE__ */ jsx3("div", { style: { flex: 1 }, children: testResult.ok && testResult.authenticated ? /* @__PURE__ */ jsxs3("div", { children: [
|
|
1939
|
+
/* @__PURE__ */ jsx3("strong", { children: "Connected successfully" }),
|
|
1940
|
+
testResult.version && /* @__PURE__ */ jsxs3("span", { children: [
|
|
1941
|
+
" \xB7 ",
|
|
1942
|
+
testResult.version
|
|
1943
|
+
] }),
|
|
1944
|
+
testResult.storage && /* @__PURE__ */ jsxs3("span", { children: [
|
|
1945
|
+
" (storage: ",
|
|
1946
|
+
testResult.storage,
|
|
1947
|
+
")"
|
|
1948
|
+
] })
|
|
1949
|
+
] }) : /* @__PURE__ */ jsxs3("div", { children: [
|
|
1950
|
+
/* @__PURE__ */ jsx3("strong", { children: "Connection failed: " }),
|
|
1951
|
+
/* @__PURE__ */ jsx3("span", { children: testResult.error || "Unable to reach daemon or token unauthorized" })
|
|
1952
|
+
] }) })
|
|
1953
|
+
]
|
|
1954
|
+
}
|
|
1955
|
+
),
|
|
1956
|
+
/* @__PURE__ */ jsxs3(
|
|
1957
|
+
"div",
|
|
1958
|
+
{
|
|
1959
|
+
style: {
|
|
1960
|
+
display: "flex",
|
|
1961
|
+
flexWrap: "wrap",
|
|
1962
|
+
alignItems: "center",
|
|
1963
|
+
gap: 10,
|
|
1964
|
+
paddingTop: 4
|
|
1965
|
+
},
|
|
1966
|
+
children: [
|
|
1967
|
+
/* @__PURE__ */ jsx3(
|
|
1968
|
+
"button",
|
|
1969
|
+
{
|
|
1970
|
+
type: "button",
|
|
1971
|
+
disabled: testing || loading,
|
|
1972
|
+
onClick: () => void handleTestConnection(),
|
|
1973
|
+
style: {
|
|
1974
|
+
padding: "8px 16px",
|
|
1975
|
+
fontSize: 13,
|
|
1976
|
+
fontWeight: 500,
|
|
1977
|
+
borderRadius: 8,
|
|
1978
|
+
border: `1px solid ${themeVar("hairline")}`,
|
|
1979
|
+
background: themeVar("panelSurface"),
|
|
1980
|
+
color: themeVar("labelPrimary"),
|
|
1981
|
+
cursor: testing ? "not-allowed" : "pointer",
|
|
1982
|
+
opacity: testing ? 0.6 : 1
|
|
1983
|
+
},
|
|
1984
|
+
children: testing ? "Testing..." : "Test Connection"
|
|
1985
|
+
}
|
|
1986
|
+
),
|
|
1987
|
+
/* @__PURE__ */ jsx3(
|
|
1988
|
+
"button",
|
|
1989
|
+
{
|
|
1990
|
+
type: "button",
|
|
1991
|
+
disabled: saving || loading,
|
|
1992
|
+
onClick: () => void handleSave(),
|
|
1993
|
+
style: {
|
|
1994
|
+
padding: "8px 18px",
|
|
1995
|
+
fontSize: 13,
|
|
1996
|
+
fontWeight: 600,
|
|
1997
|
+
borderRadius: 8,
|
|
1998
|
+
border: "none",
|
|
1999
|
+
background: themeVar("buttonPrimaryFill"),
|
|
2000
|
+
color: themeVar("buttonPrimaryText"),
|
|
2001
|
+
cursor: saving ? "not-allowed" : "pointer",
|
|
2002
|
+
opacity: saving ? 0.6 : 1
|
|
2003
|
+
},
|
|
2004
|
+
children: saving ? "Saving..." : "Save Settings"
|
|
2005
|
+
}
|
|
2006
|
+
),
|
|
2007
|
+
source === "settings" && /* @__PURE__ */ jsx3(
|
|
2008
|
+
"button",
|
|
2009
|
+
{
|
|
2010
|
+
type: "button",
|
|
2011
|
+
disabled: saving || loading,
|
|
2012
|
+
onClick: () => void handleReset(),
|
|
2013
|
+
style: {
|
|
2014
|
+
padding: "8px 14px",
|
|
2015
|
+
fontSize: 13,
|
|
2016
|
+
fontWeight: 500,
|
|
2017
|
+
borderRadius: 8,
|
|
2018
|
+
border: `1px solid ${themeVar("hairline")}`,
|
|
2019
|
+
background: "transparent",
|
|
2020
|
+
color: themeVar("labelSecondary"),
|
|
2021
|
+
cursor: "pointer",
|
|
2022
|
+
marginLeft: "auto"
|
|
2023
|
+
},
|
|
2024
|
+
children: "Reset to Auto-detected"
|
|
2025
|
+
}
|
|
2026
|
+
),
|
|
2027
|
+
flash && /* @__PURE__ */ jsx3(
|
|
2028
|
+
"span",
|
|
2029
|
+
{
|
|
2030
|
+
style: {
|
|
2031
|
+
fontSize: 13,
|
|
2032
|
+
color: flash.kind === "ok" ? themeVar("stateSuccess") : themeVar("stateError"),
|
|
2033
|
+
fontWeight: 500
|
|
2034
|
+
},
|
|
2035
|
+
children: flash.message
|
|
2036
|
+
}
|
|
2037
|
+
)
|
|
2038
|
+
]
|
|
2039
|
+
}
|
|
2040
|
+
)
|
|
2041
|
+
]
|
|
2042
|
+
}
|
|
2043
|
+
),
|
|
2044
|
+
/* @__PURE__ */ jsxs3(
|
|
2045
|
+
"div",
|
|
2046
|
+
{
|
|
2047
|
+
style: {
|
|
2048
|
+
border: `1px solid ${themeVar("hairline")}`,
|
|
2049
|
+
borderRadius: 10,
|
|
2050
|
+
padding: "14px 18px",
|
|
2051
|
+
background: themeVar("panelSurface"),
|
|
2052
|
+
fontSize: 13,
|
|
2053
|
+
color: themeVar("labelSecondary"),
|
|
2054
|
+
lineHeight: 1.5
|
|
2055
|
+
},
|
|
2056
|
+
children: [
|
|
2057
|
+
/* @__PURE__ */ jsx3(
|
|
2058
|
+
"p",
|
|
2059
|
+
{
|
|
2060
|
+
style: {
|
|
2061
|
+
margin: "0 0 6px 0",
|
|
2062
|
+
fontWeight: 600,
|
|
2063
|
+
color: themeVar("labelPrimary")
|
|
2064
|
+
},
|
|
2065
|
+
children: "How OpenViking connection works:"
|
|
2066
|
+
}
|
|
2067
|
+
),
|
|
2068
|
+
/* @__PURE__ */ jsxs3("ul", { style: { margin: 0, paddingLeft: 18 }, children: [
|
|
2069
|
+
/* @__PURE__ */ jsx3("li", { style: { marginBottom: 4 }, children: "All requests to OpenViking proxy through the DSH Desktop host, making it work seamlessly even when managing DSH remotely over Tailscale, mobile, or LAN." }),
|
|
2070
|
+
/* @__PURE__ */ jsxs3("li", { style: { marginBottom: 4 }, children: [
|
|
2071
|
+
"If OpenViking runs locally on the standard port (1933), the plugin auto-detects credentials from ",
|
|
2072
|
+
/* @__PURE__ */ jsx3("code", { children: "~/.openviking/ovcli.conf" }),
|
|
2073
|
+
"."
|
|
2074
|
+
] }),
|
|
2075
|
+
/* @__PURE__ */ jsxs3("li", { children: [
|
|
2076
|
+
"Custom values saved here are persisted in",
|
|
2077
|
+
" ",
|
|
2078
|
+
/* @__PURE__ */ jsx3("code", { children: "~/.dsh/settings.yaml" }),
|
|
2079
|
+
" under the",
|
|
2080
|
+
" ",
|
|
2081
|
+
/* @__PURE__ */ jsx3("code", { children: "openviking-status" }),
|
|
2082
|
+
" namespace."
|
|
2083
|
+
] })
|
|
2084
|
+
] })
|
|
2085
|
+
]
|
|
2086
|
+
}
|
|
2087
|
+
)
|
|
2088
|
+
]
|
|
2089
|
+
}
|
|
2090
|
+
);
|
|
1376
2091
|
}
|
|
1377
2092
|
|
|
1378
2093
|
// src/client/index.tsx
|
|
@@ -1381,10 +2096,10 @@ var inject = ["slots"];
|
|
|
1381
2096
|
function apply(ctx) {
|
|
1382
2097
|
ctx.effect(
|
|
1383
2098
|
() => ctx.slots.inject(
|
|
1384
|
-
"conversation.
|
|
2099
|
+
"conversation.composer.dock",
|
|
1385
2100
|
() => ctx.slots.register(
|
|
1386
2101
|
{
|
|
1387
|
-
name: "conversation.
|
|
2102
|
+
name: "conversation.composer.dock",
|
|
1388
2103
|
id: "openviking-status",
|
|
1389
2104
|
order: 50,
|
|
1390
2105
|
label: "OpenViking"
|
|
@@ -1392,20 +2107,39 @@ function apply(ctx) {
|
|
|
1392
2107
|
OpenVikingStatusChip
|
|
1393
2108
|
)
|
|
1394
2109
|
),
|
|
1395
|
-
"openviking-status: composer chip"
|
|
2110
|
+
"openviking-status: composer stats chip"
|
|
2111
|
+
);
|
|
2112
|
+
ctx.effect(
|
|
2113
|
+
() => ctx.slots.inject(
|
|
2114
|
+
"settings.section",
|
|
2115
|
+
() => ctx.slots.register(
|
|
2116
|
+
{
|
|
2117
|
+
name: "settings.section",
|
|
2118
|
+
id: "openviking-status",
|
|
2119
|
+
order: 35,
|
|
2120
|
+
label: () => "OpenViking"
|
|
2121
|
+
},
|
|
2122
|
+
OpenVikingSettingsSection
|
|
2123
|
+
)
|
|
2124
|
+
),
|
|
2125
|
+
"openviking-status: settings section"
|
|
1396
2126
|
);
|
|
1397
2127
|
}
|
|
1398
2128
|
export {
|
|
1399
2129
|
COMMIT_THRESHOLD,
|
|
1400
2130
|
DEFAULT_OPENVIKING_ENDPOINT,
|
|
1401
2131
|
OpenVikingClient,
|
|
2132
|
+
OpenVikingSettingsSection,
|
|
1402
2133
|
OpenVikingStatusChip,
|
|
1403
2134
|
OpenVikingStatusPopover,
|
|
2135
|
+
THEME,
|
|
1404
2136
|
apply,
|
|
2137
|
+
chatNodesToText,
|
|
1405
2138
|
checkHealth,
|
|
1406
2139
|
commitSession,
|
|
1407
2140
|
defaultOpenVikingClient,
|
|
1408
2141
|
fetchSession,
|
|
2142
|
+
formatDaemonVersion,
|
|
1409
2143
|
formatEndpoint,
|
|
1410
2144
|
formatMemoryLeafName,
|
|
1411
2145
|
formatPendingTokens,
|
|
@@ -1413,11 +2147,9 @@ export {
|
|
|
1413
2147
|
formatStatusLabel,
|
|
1414
2148
|
formatTooltipTitle,
|
|
1415
2149
|
getCategoryBadgeStyle,
|
|
1416
|
-
getFallbackSessionMessages,
|
|
1417
2150
|
getProgressBarColor,
|
|
1418
2151
|
getProgressBarPercent,
|
|
1419
2152
|
getSession,
|
|
1420
|
-
getStatusGlow,
|
|
1421
2153
|
getStatusIndicatorColor,
|
|
1422
2154
|
handleEscapeKey,
|
|
1423
2155
|
inferCategory,
|
|
@@ -1426,6 +2158,7 @@ export {
|
|
|
1426
2158
|
parseRecalledMemories,
|
|
1427
2159
|
resolveApiKey,
|
|
1428
2160
|
resolveEndpoint,
|
|
2161
|
+
themeVar,
|
|
1429
2162
|
truncateSessionId
|
|
1430
2163
|
};
|
|
1431
2164
|
//# sourceMappingURL=client.js.map
|