reasonix 0.23.1 → 0.24.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/dashboard/dist/app.js +1723 -574
- package/dashboard/dist/app.js.map +1 -1
- package/dist/cli/.-3G6VX5S7.js +327 -0
- package/dist/cli/.-6YRPB2C7.js +329 -0
- package/dist/cli/.-6YRPB2C7.js.map +1 -0
- package/dist/cli/.-EYSVINK3.js +317 -0
- package/dist/cli/.-EYSVINK3.js.map +1 -0
- package/dist/cli/banner-demo-QKOPDSTL.js +77 -0
- package/dist/cli/banner-demo-QKOPDSTL.js.map +1 -0
- package/dist/cli/card-demo-5TVXJISK.js +944 -0
- package/dist/cli/card-demo-5TVXJISK.js.map +1 -0
- package/dist/cli/chunk-2H7UOFLK.js +11 -0
- package/dist/cli/chunk-2H7UOFLK.js.map +1 -0
- package/dist/cli/chunk-BGTXZKNY.js +197 -0
- package/dist/cli/chunk-BGTXZKNY.js.map +1 -0
- package/dist/cli/chunk-JHXQDL7B.js +2056 -0
- package/dist/cli/chunk-JHXQDL7B.js.map +1 -0
- package/dist/cli/flicker-demo-MOB6GAW4.js +165 -0
- package/dist/cli/flicker-demo-MOB6GAW4.js.map +1 -0
- package/dist/cli/index.js +3654 -2035
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/preview-4FOEEE5G.js +224 -0
- package/dist/cli/preview-4FOEEE5G.js.map +1 -0
- package/dist/cli/{prompt-YUL7CYKY.js → prompt-VZQ2CPID.js} +2 -1
- package/dist/cli/prompt-VZQ2CPID.js.map +1 -0
- package/dist/cli/renderer-demo-2BIGEV2T.js +95 -0
- package/dist/cli/renderer-demo-2BIGEV2T.js.map +1 -0
- package/dist/cli/select-demo-OA5N34BJ.js +107 -0
- package/dist/cli/select-demo-OA5N34BJ.js.map +1 -0
- package/dist/cli/stress-demo-I7XRPQMM.js +211 -0
- package/dist/cli/stress-demo-I7XRPQMM.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +22 -9
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
- /package/dist/cli/{prompt-YUL7CYKY.js.map → .-3G6VX5S7.js.map} +0 -0
package/dashboard/dist/app.js
CHANGED
|
@@ -1355,8 +1355,8 @@ var require_core = __commonJS({
|
|
|
1355
1355
|
result.secondBest = secondBest;
|
|
1356
1356
|
return result;
|
|
1357
1357
|
}
|
|
1358
|
-
function updateClassName(element,
|
|
1359
|
-
const language =
|
|
1358
|
+
function updateClassName(element, currentLang2, resultLang) {
|
|
1359
|
+
const language = currentLang2 && aliases[currentLang2] || resultLang;
|
|
1360
1360
|
element.classList.add("hljs");
|
|
1361
1361
|
element.classList.add(`language-${language}`);
|
|
1362
1362
|
}
|
|
@@ -14118,8 +14118,8 @@ function join(tables, nullModes) {
|
|
|
14118
14118
|
}
|
|
14119
14119
|
let xVals = /* @__PURE__ */ new Set();
|
|
14120
14120
|
for (let ti = 0; ti < tables.length; ti++) {
|
|
14121
|
-
let
|
|
14122
|
-
let xs =
|
|
14121
|
+
let t5 = tables[ti];
|
|
14122
|
+
let xs = t5[0];
|
|
14123
14123
|
let len = xs.length;
|
|
14124
14124
|
for (let i3 = 0; i3 < len; i3++)
|
|
14125
14125
|
xVals.add(xs[i3]);
|
|
@@ -14130,10 +14130,10 @@ function join(tables, nullModes) {
|
|
|
14130
14130
|
for (let i3 = 0; i3 < alignedLen; i3++)
|
|
14131
14131
|
xIdxs.set(data[0][i3], i3);
|
|
14132
14132
|
for (let ti = 0; ti < tables.length; ti++) {
|
|
14133
|
-
let
|
|
14134
|
-
let xs =
|
|
14135
|
-
for (let si = 1; si <
|
|
14136
|
-
let ys =
|
|
14133
|
+
let t5 = tables[ti];
|
|
14134
|
+
let xs = t5[0];
|
|
14135
|
+
for (let si = 1; si < t5.length; si++) {
|
|
14136
|
+
let ys = t5[si];
|
|
14137
14137
|
let yVals = Array(alignedLen).fill(void 0);
|
|
14138
14138
|
let nullMode = nullModes ? nullModes[ti][si] : NULL_RETAIN;
|
|
14139
14139
|
let nullIdxs = [];
|
|
@@ -14580,7 +14580,7 @@ function orient(u3, seriesIdx, cb) {
|
|
|
14580
14580
|
const data = mode == 2 ? u3._data[seriesIdx] : u3._data;
|
|
14581
14581
|
const scales = u3.scales;
|
|
14582
14582
|
const bbox = u3.bbox;
|
|
14583
|
-
let dx = data[0], dy = mode == 2 ? data[1] : data[seriesIdx], sx = mode == 2 ? scales[series.facets[0].scale] : scales[u3.series[0].scale], sy = mode == 2 ? scales[series.facets[1].scale] : scales[series.scale], l3 = bbox.left,
|
|
14583
|
+
let dx = data[0], dy = mode == 2 ? data[1] : data[seriesIdx], sx = mode == 2 ? scales[series.facets[0].scale] : scales[u3.series[0].scale], sy = mode == 2 ? scales[series.facets[1].scale] : scales[series.scale], l3 = bbox.left, t5 = bbox.top, w3 = bbox.width, h3 = bbox.height, H = u3.valToPosH, V2 = u3.valToPosV;
|
|
14584
14584
|
return sx.ori == 0 ? cb(
|
|
14585
14585
|
series,
|
|
14586
14586
|
dx,
|
|
@@ -14590,7 +14590,7 @@ function orient(u3, seriesIdx, cb) {
|
|
|
14590
14590
|
H,
|
|
14591
14591
|
V2,
|
|
14592
14592
|
l3,
|
|
14593
|
-
|
|
14593
|
+
t5,
|
|
14594
14594
|
w3,
|
|
14595
14595
|
h3,
|
|
14596
14596
|
moveToH,
|
|
@@ -14606,7 +14606,7 @@ function orient(u3, seriesIdx, cb) {
|
|
|
14606
14606
|
sy,
|
|
14607
14607
|
V2,
|
|
14608
14608
|
H,
|
|
14609
|
-
|
|
14609
|
+
t5,
|
|
14610
14610
|
l3,
|
|
14611
14611
|
h3,
|
|
14612
14612
|
w3,
|
|
@@ -18019,12 +18019,12 @@ var init_uPlot_esm = __esm({
|
|
|
18019
18019
|
});
|
|
18020
18020
|
|
|
18021
18021
|
// node_modules/htm/dist/htm.module.js
|
|
18022
|
-
var n = function(
|
|
18022
|
+
var n = function(t5, s3, r3, e3) {
|
|
18023
18023
|
var u3;
|
|
18024
18024
|
s3[0] = 0;
|
|
18025
18025
|
for (var h3 = 1; h3 < s3.length; h3++) {
|
|
18026
18026
|
var p3 = s3[h3++], a3 = s3[h3] ? (s3[0] |= p3 ? 1 : 2, r3[s3[h3++]]) : s3[++h3];
|
|
18027
|
-
3 === p3 ? e3[0] = a3 : 4 === p3 ? e3[1] = Object.assign(e3[1] || {}, a3) : 5 === p3 ? (e3[1] = e3[1] || {})[s3[++h3]] = a3 : 6 === p3 ? e3[1][s3[++h3]] += a3 + "" : p3 ? (u3 =
|
|
18027
|
+
3 === p3 ? e3[0] = a3 : 4 === p3 ? e3[1] = Object.assign(e3[1] || {}, a3) : 5 === p3 ? (e3[1] = e3[1] || {})[s3[++h3]] = a3 : 6 === p3 ? e3[1][s3[++h3]] += a3 + "" : p3 ? (u3 = t5.apply(a3, n(t5, a3, r3, ["", null])), e3.push(u3), a3[0] ? s3[0] |= 2 : (s3[h3 - 2] = 0, s3[h3] = u3)) : e3.push(a3);
|
|
18028
18028
|
}
|
|
18029
18029
|
return e3;
|
|
18030
18030
|
};
|
|
@@ -18032,11 +18032,11 @@ var t = /* @__PURE__ */ new Map();
|
|
|
18032
18032
|
function htm_module_default(s3) {
|
|
18033
18033
|
var r3 = t.get(this);
|
|
18034
18034
|
return r3 || (r3 = /* @__PURE__ */ new Map(), t.set(this, r3)), (r3 = n(this, r3.get(s3) || (r3.set(s3, r3 = (function(n3) {
|
|
18035
|
-
for (var
|
|
18035
|
+
for (var t5, s4, r4 = 1, e3 = "", u3 = "", h3 = [0], p3 = function(n4) {
|
|
18036
18036
|
1 === r4 && (n4 || (e3 = e3.replace(/^\s*\n\s*|\s*\n\s*$/g, ""))) ? h3.push(0, n4, e3) : 3 === r4 && (n4 || e3) ? (h3.push(3, n4, e3), r4 = 2) : 2 === r4 && "..." === e3 && n4 ? h3.push(4, n4, 0) : 2 === r4 && e3 && !n4 ? h3.push(5, 0, true, e3) : r4 >= 5 && ((e3 || !n4 && 5 === r4) && (h3.push(r4, 0, e3, s4), r4 = 6), n4 && (h3.push(r4, n4, 0, s4), r4 = 6)), e3 = "";
|
|
18037
18037
|
}, a3 = 0; a3 < n3.length; a3++) {
|
|
18038
18038
|
a3 && (1 === r4 && p3(), p3(a3));
|
|
18039
|
-
for (var l3 = 0; l3 < n3[a3].length; l3++)
|
|
18039
|
+
for (var l3 = 0; l3 < n3[a3].length; l3++) t5 = n3[a3][l3], 1 === r4 ? "<" === t5 ? (p3(), h3 = [h3], r4 = 3) : e3 += t5 : 4 === r4 ? "--" === e3 && ">" === t5 ? (r4 = 1, e3 = "") : e3 = t5 + e3[0] : u3 ? t5 === u3 ? u3 = "" : e3 += t5 : '"' === t5 || "'" === t5 ? u3 = t5 : ">" === t5 ? (p3(), r4 = 1) : r4 && ("=" === t5 ? (r4 = 5, s4 = e3, e3 = "") : "/" === t5 && (r4 < 5 || ">" === n3[a3][l3 + 1]) ? (p3(), 3 === r4 && (h3 = h3[0]), r4 = h3, (h3 = h3[0]).push(2, 0, r4), r4 = 0) : " " === t5 || " " === t5 || "\n" === t5 || "\r" === t5 ? (p3(), r4 = 2) : e3 += t5), 3 === r4 && "!--" === e3 && (r4 = 4, h3 = h3[0]);
|
|
18040
18040
|
}
|
|
18041
18041
|
return p3(), h3;
|
|
18042
18042
|
})(s3)), r3), arguments, [])).length > 1 ? r3 : r3[0];
|
|
@@ -18067,14 +18067,14 @@ function w(n3) {
|
|
|
18067
18067
|
var l3 = n3.parentNode;
|
|
18068
18068
|
l3 && l3.removeChild(n3);
|
|
18069
18069
|
}
|
|
18070
|
-
function _(l3, u3,
|
|
18070
|
+
function _(l3, u3, t5) {
|
|
18071
18071
|
var i3, o3, r3, f3 = {};
|
|
18072
18072
|
for (r3 in u3) "key" == r3 ? i3 = u3[r3] : "ref" == r3 ? o3 = u3[r3] : f3[r3] = u3[r3];
|
|
18073
|
-
if (arguments.length > 2 && (f3.children = arguments.length > 3 ? n2.call(arguments, 2) :
|
|
18073
|
+
if (arguments.length > 2 && (f3.children = arguments.length > 3 ? n2.call(arguments, 2) : t5), "function" == typeof l3 && null != l3.defaultProps) for (r3 in l3.defaultProps) void 0 === f3[r3] && (f3[r3] = l3.defaultProps[r3]);
|
|
18074
18074
|
return g(l3, f3, i3, o3, null);
|
|
18075
18075
|
}
|
|
18076
|
-
function g(n3,
|
|
18077
|
-
var f3 = { type: n3, props:
|
|
18076
|
+
function g(n3, t5, i3, o3, r3) {
|
|
18077
|
+
var f3 = { type: n3, props: t5, key: i3, ref: o3, __k: null, __: null, __b: 0, __e: null, __d: void 0, __c: null, constructor: void 0, __v: null == r3 ? ++u : r3, __i: -1, __u: 0 };
|
|
18078
18078
|
return null == r3 && null != l.vnode && l.vnode(f3), f3;
|
|
18079
18079
|
}
|
|
18080
18080
|
function k(n3) {
|
|
@@ -18102,24 +18102,24 @@ function M(n3) {
|
|
|
18102
18102
|
(!n3.__d && (n3.__d = true) && i.push(n3) && !P.__r++ || o !== l.debounceRendering) && ((o = l.debounceRendering) || r)(P);
|
|
18103
18103
|
}
|
|
18104
18104
|
function P() {
|
|
18105
|
-
var n3, u3,
|
|
18106
|
-
for (i.sort(f); n3 = i.shift(); ) n3.__d && (u3 = i.length, o3 = void 0, e3 = (r3 = (
|
|
18105
|
+
var n3, u3, t5, o3, r3, e3, c3, s3;
|
|
18106
|
+
for (i.sort(f); n3 = i.shift(); ) n3.__d && (u3 = i.length, o3 = void 0, e3 = (r3 = (t5 = n3).__v).__e, c3 = [], s3 = [], t5.__P && ((o3 = d({}, r3)).__v = r3.__v + 1, l.vnode && l.vnode(o3), O(t5.__P, o3, r3, t5.__n, t5.__P.namespaceURI, 32 & r3.__u ? [e3] : null, c3, null == e3 ? x(r3) : e3, !!(32 & r3.__u), s3), o3.__v = r3.__v, o3.__.__k[o3.__i] = o3, j(c3, o3, s3), o3.__e != e3 && C(o3)), i.length > u3 && i.sort(f));
|
|
18107
18107
|
P.__r = 0;
|
|
18108
18108
|
}
|
|
18109
|
-
function S(n3, l3, u3,
|
|
18110
|
-
var a3, v3, y3, d3, w3, _4 =
|
|
18109
|
+
function S(n3, l3, u3, t5, i3, o3, r3, f3, e3, c3, s3) {
|
|
18110
|
+
var a3, v3, y3, d3, w3, _4 = t5 && t5.__k || p, g2 = l3.length;
|
|
18111
18111
|
for (u3.__d = e3, $(u3, l3, _4), e3 = u3.__d, a3 = 0; a3 < g2; a3++) null != (y3 = u3.__k[a3]) && "boolean" != typeof y3 && "function" != typeof y3 && (v3 = -1 === y3.__i ? h : _4[y3.__i] || h, y3.__i = a3, O(n3, y3, v3, i3, o3, r3, f3, e3, c3, s3), d3 = y3.__e, y3.ref && v3.ref != y3.ref && (v3.ref && N(v3.ref, null, y3), s3.push(y3.ref, y3.__c || d3, y3)), null == w3 && null != d3 && (w3 = d3), 65536 & y3.__u || v3.__k === y3.__k ? (e3 && !e3.isConnected && (e3 = x(v3)), e3 = I(y3, e3, n3)) : "function" == typeof y3.type && void 0 !== y3.__d ? e3 = y3.__d : d3 && (e3 = d3.nextSibling), y3.__d = void 0, y3.__u &= -196609);
|
|
18112
18112
|
u3.__d = e3, u3.__e = w3;
|
|
18113
18113
|
}
|
|
18114
18114
|
function $(n3, l3, u3) {
|
|
18115
|
-
var
|
|
18116
|
-
for (n3.__k = [],
|
|
18117
|
-
if (s3) for (
|
|
18115
|
+
var t5, i3, o3, r3, f3, e3 = l3.length, c3 = u3.length, s3 = c3, a3 = 0;
|
|
18116
|
+
for (n3.__k = [], t5 = 0; t5 < e3; t5++) r3 = t5 + a3, null != (i3 = n3.__k[t5] = null == (i3 = l3[t5]) || "boolean" == typeof i3 || "function" == typeof i3 ? null : "string" == typeof i3 || "number" == typeof i3 || "bigint" == typeof i3 || i3.constructor == String ? g(null, i3, null, null, null) : y(i3) ? g(k, { children: i3 }, null, null, null) : void 0 === i3.constructor && i3.__b > 0 ? g(i3.type, i3.props, i3.key, i3.ref ? i3.ref : null, i3.__v) : i3) ? (i3.__ = n3, i3.__b = n3.__b + 1, f3 = L(i3, u3, r3, s3), i3.__i = f3, o3 = null, -1 !== f3 && (s3--, (o3 = u3[f3]) && (o3.__u |= 131072)), null == o3 || null === o3.__v ? (-1 == f3 && a3--, "function" != typeof i3.type && (i3.__u |= 65536)) : f3 !== r3 && (f3 === r3 + 1 ? a3++ : f3 > r3 ? s3 > e3 - r3 ? a3 += f3 - r3 : a3-- : f3 < r3 ? f3 == r3 - 1 && (a3 = f3 - r3) : a3 = 0, f3 !== t5 + a3 && (i3.__u |= 65536))) : (o3 = u3[r3]) && null == o3.key && o3.__e && 0 == (131072 & o3.__u) && (o3.__e == n3.__d && (n3.__d = x(o3)), V(o3, o3, false), u3[r3] = null, s3--);
|
|
18117
|
+
if (s3) for (t5 = 0; t5 < c3; t5++) null != (o3 = u3[t5]) && 0 == (131072 & o3.__u) && (o3.__e == n3.__d && (n3.__d = x(o3)), V(o3, o3));
|
|
18118
18118
|
}
|
|
18119
18119
|
function I(n3, l3, u3) {
|
|
18120
|
-
var
|
|
18120
|
+
var t5, i3;
|
|
18121
18121
|
if ("function" == typeof n3.type) {
|
|
18122
|
-
for (
|
|
18122
|
+
for (t5 = n3.__k, i3 = 0; t5 && i3 < t5.length; i3++) t5[i3] && (t5[i3].__ = n3, l3 = I(t5[i3], l3, u3));
|
|
18123
18123
|
return l3;
|
|
18124
18124
|
}
|
|
18125
18125
|
n3.__e != l3 && (u3.insertBefore(n3.__e, l3 || null), l3 = n3.__e);
|
|
@@ -18128,10 +18128,10 @@ function I(n3, l3, u3) {
|
|
|
18128
18128
|
} while (null != l3 && 8 === l3.nodeType);
|
|
18129
18129
|
return l3;
|
|
18130
18130
|
}
|
|
18131
|
-
function L(n3, l3, u3,
|
|
18131
|
+
function L(n3, l3, u3, t5) {
|
|
18132
18132
|
var i3 = n3.key, o3 = n3.type, r3 = u3 - 1, f3 = u3 + 1, e3 = l3[u3];
|
|
18133
18133
|
if (null === e3 || e3 && i3 == e3.key && o3 === e3.type && 0 == (131072 & e3.__u)) return u3;
|
|
18134
|
-
if (
|
|
18134
|
+
if (t5 > (null != e3 && 0 == (131072 & e3.__u) ? 1 : 0)) for (; r3 >= 0 || f3 < l3.length; ) {
|
|
18135
18135
|
if (r3 >= 0) {
|
|
18136
18136
|
if ((e3 = l3[r3]) && 0 == (131072 & e3.__u) && i3 == e3.key && o3 === e3.type) return r3;
|
|
18137
18137
|
r3--;
|
|
@@ -18146,14 +18146,14 @@ function L(n3, l3, u3, t4) {
|
|
|
18146
18146
|
function T(n3, l3, u3) {
|
|
18147
18147
|
"-" === l3[0] ? n3.setProperty(l3, null == u3 ? "" : u3) : n3[l3] = null == u3 ? "" : "number" != typeof u3 || v.test(l3) ? u3 : u3 + "px";
|
|
18148
18148
|
}
|
|
18149
|
-
function A(n3, l3, u3,
|
|
18149
|
+
function A(n3, l3, u3, t5, i3) {
|
|
18150
18150
|
var o3;
|
|
18151
18151
|
n: if ("style" === l3) if ("string" == typeof u3) n3.style.cssText = u3;
|
|
18152
18152
|
else {
|
|
18153
|
-
if ("string" == typeof
|
|
18154
|
-
if (u3) for (l3 in u3)
|
|
18153
|
+
if ("string" == typeof t5 && (n3.style.cssText = t5 = ""), t5) for (l3 in t5) u3 && l3 in u3 || T(n3.style, l3, "");
|
|
18154
|
+
if (u3) for (l3 in u3) t5 && u3[l3] === t5[l3] || T(n3.style, l3, u3[l3]);
|
|
18155
18155
|
}
|
|
18156
|
-
else if ("o" === l3[0] && "n" === l3[1]) o3 = l3 !== (l3 = l3.replace(/(PointerCapture)$|Capture$/i, "$1")), l3 = l3.toLowerCase() in n3 || "onFocusOut" === l3 || "onFocusIn" === l3 ? l3.toLowerCase().slice(2) : l3.slice(2), n3.l || (n3.l = {}), n3.l[l3 + o3] = u3, u3 ?
|
|
18156
|
+
else if ("o" === l3[0] && "n" === l3[1]) o3 = l3 !== (l3 = l3.replace(/(PointerCapture)$|Capture$/i, "$1")), l3 = l3.toLowerCase() in n3 || "onFocusOut" === l3 || "onFocusIn" === l3 ? l3.toLowerCase().slice(2) : l3.slice(2), n3.l || (n3.l = {}), n3.l[l3 + o3] = u3, u3 ? t5 ? u3.u = t5.u : (u3.u = e, n3.addEventListener(l3, o3 ? s : c, o3)) : n3.removeEventListener(l3, o3 ? s : c, o3);
|
|
18157
18157
|
else {
|
|
18158
18158
|
if ("http://www.w3.org/2000/svg" == i3) l3 = l3.replace(/xlink(H|:h)/, "h").replace(/sName$/, "s");
|
|
18159
18159
|
else if ("width" != l3 && "height" != l3 && "href" != l3 && "list" != l3 && "form" != l3 && "tabIndex" != l3 && "download" != l3 && "rowSpan" != l3 && "colSpan" != l3 && "role" != l3 && l3 in n3) try {
|
|
@@ -18167,22 +18167,22 @@ function A(n3, l3, u3, t4, i3) {
|
|
|
18167
18167
|
function F(n3) {
|
|
18168
18168
|
return function(u3) {
|
|
18169
18169
|
if (this.l) {
|
|
18170
|
-
var
|
|
18170
|
+
var t5 = this.l[u3.type + n3];
|
|
18171
18171
|
if (null == u3.t) u3.t = e++;
|
|
18172
|
-
else if (u3.t <
|
|
18173
|
-
return
|
|
18172
|
+
else if (u3.t < t5.u) return;
|
|
18173
|
+
return t5(l.event ? l.event(u3) : u3);
|
|
18174
18174
|
}
|
|
18175
18175
|
};
|
|
18176
18176
|
}
|
|
18177
|
-
function O(n3, u3,
|
|
18177
|
+
function O(n3, u3, t5, i3, o3, r3, f3, e3, c3, s3) {
|
|
18178
18178
|
var a3, h3, p3, v3, w3, _4, g2, m2, x3, C3, M3, P2, $2, I2, H, L2 = u3.type;
|
|
18179
18179
|
if (void 0 !== u3.constructor) return null;
|
|
18180
|
-
128 &
|
|
18180
|
+
128 & t5.__u && (c3 = !!(32 & t5.__u), r3 = [e3 = u3.__e = t5.__e]), (a3 = l.__b) && a3(u3);
|
|
18181
18181
|
n: if ("function" == typeof L2) try {
|
|
18182
|
-
if (m2 = u3.props, x3 = (a3 = L2.contextType) && i3[a3.__c], C3 = a3 ? x3 ? x3.props.value : a3.__ : i3,
|
|
18182
|
+
if (m2 = u3.props, x3 = (a3 = L2.contextType) && i3[a3.__c], C3 = a3 ? x3 ? x3.props.value : a3.__ : i3, t5.__c ? g2 = (h3 = u3.__c = t5.__c).__ = h3.__E : ("prototype" in L2 && L2.prototype.render ? u3.__c = h3 = new L2(m2, C3) : (u3.__c = h3 = new b(m2, C3), h3.constructor = L2, h3.render = q), x3 && x3.sub(h3), h3.props = m2, h3.state || (h3.state = {}), h3.context = C3, h3.__n = i3, p3 = h3.__d = true, h3.__h = [], h3._sb = []), null == h3.__s && (h3.__s = h3.state), null != L2.getDerivedStateFromProps && (h3.__s == h3.state && (h3.__s = d({}, h3.__s)), d(h3.__s, L2.getDerivedStateFromProps(m2, h3.__s))), v3 = h3.props, w3 = h3.state, h3.__v = u3, p3) null == L2.getDerivedStateFromProps && null != h3.componentWillMount && h3.componentWillMount(), null != h3.componentDidMount && h3.__h.push(h3.componentDidMount);
|
|
18183
18183
|
else {
|
|
18184
|
-
if (null == L2.getDerivedStateFromProps && m2 !== v3 && null != h3.componentWillReceiveProps && h3.componentWillReceiveProps(m2, C3), !h3.__e && (null != h3.shouldComponentUpdate && false === h3.shouldComponentUpdate(m2, h3.__s, C3) || u3.__v ===
|
|
18185
|
-
for (u3.__v !==
|
|
18184
|
+
if (null == L2.getDerivedStateFromProps && m2 !== v3 && null != h3.componentWillReceiveProps && h3.componentWillReceiveProps(m2, C3), !h3.__e && (null != h3.shouldComponentUpdate && false === h3.shouldComponentUpdate(m2, h3.__s, C3) || u3.__v === t5.__v)) {
|
|
18185
|
+
for (u3.__v !== t5.__v && (h3.props = m2, h3.state = h3.__s, h3.__d = false), u3.__e = t5.__e, u3.__k = t5.__k, u3.__k.forEach(function(n4) {
|
|
18186
18186
|
n4 && (n4.__ = u3);
|
|
18187
18187
|
}), M3 = 0; M3 < h3._sb.length; M3++) h3.__h.push(h3._sb[M3]);
|
|
18188
18188
|
h3._sb = [], h3.__h.length && f3.push(h3);
|
|
@@ -18198,16 +18198,16 @@ function O(n3, u3, t4, i3, o3, r3, f3, e3, c3, s3) {
|
|
|
18198
18198
|
} else do {
|
|
18199
18199
|
h3.__d = false, P2 && P2(u3), a3 = h3.render(h3.props, h3.state, h3.context), h3.state = h3.__s;
|
|
18200
18200
|
} while (h3.__d && ++$2 < 25);
|
|
18201
|
-
h3.state = h3.__s, null != h3.getChildContext && (i3 = d(d({}, i3), h3.getChildContext())), p3 || null == h3.getSnapshotBeforeUpdate || (_4 = h3.getSnapshotBeforeUpdate(v3, w3)), S(n3, y(H = null != a3 && a3.type === k && null == a3.key ? a3.props.children : a3) ? H : [H], u3,
|
|
18201
|
+
h3.state = h3.__s, null != h3.getChildContext && (i3 = d(d({}, i3), h3.getChildContext())), p3 || null == h3.getSnapshotBeforeUpdate || (_4 = h3.getSnapshotBeforeUpdate(v3, w3)), S(n3, y(H = null != a3 && a3.type === k && null == a3.key ? a3.props.children : a3) ? H : [H], u3, t5, i3, o3, r3, f3, e3, c3, s3), h3.base = u3.__e, u3.__u &= -161, h3.__h.length && f3.push(h3), g2 && (h3.__E = h3.__ = null);
|
|
18202
18202
|
} catch (n4) {
|
|
18203
|
-
u3.__v = null, c3 || null != r3 ? (u3.__e = e3, u3.__u |= c3 ? 160 : 32, r3[r3.indexOf(e3)] = null) : (u3.__e =
|
|
18203
|
+
u3.__v = null, c3 || null != r3 ? (u3.__e = e3, u3.__u |= c3 ? 160 : 32, r3[r3.indexOf(e3)] = null) : (u3.__e = t5.__e, u3.__k = t5.__k), l.__e(n4, u3, t5);
|
|
18204
18204
|
}
|
|
18205
|
-
else null == r3 && u3.__v ===
|
|
18205
|
+
else null == r3 && u3.__v === t5.__v ? (u3.__k = t5.__k, u3.__e = t5.__e) : u3.__e = z(t5.__e, u3, t5, i3, o3, r3, f3, c3, s3);
|
|
18206
18206
|
(a3 = l.diffed) && a3(u3);
|
|
18207
18207
|
}
|
|
18208
|
-
function j(n3, u3,
|
|
18208
|
+
function j(n3, u3, t5) {
|
|
18209
18209
|
u3.__d = void 0;
|
|
18210
|
-
for (var i3 = 0; i3 <
|
|
18210
|
+
for (var i3 = 0; i3 < t5.length; i3++) N(t5[i3], t5[++i3], t5[++i3]);
|
|
18211
18211
|
l.__c && l.__c(u3, n3), n3.some(function(u4) {
|
|
18212
18212
|
try {
|
|
18213
18213
|
n3 = u4.__h, u4.__h = [], n3.some(function(n4) {
|
|
@@ -18218,8 +18218,8 @@ function j(n3, u3, t4) {
|
|
|
18218
18218
|
}
|
|
18219
18219
|
});
|
|
18220
18220
|
}
|
|
18221
|
-
function z(l3, u3,
|
|
18222
|
-
var s3, a3, p3, v3, d3, _4, g2, m2 =
|
|
18221
|
+
function z(l3, u3, t5, i3, o3, r3, f3, e3, c3) {
|
|
18222
|
+
var s3, a3, p3, v3, d3, _4, g2, m2 = t5.props, k3 = u3.props, b2 = u3.type;
|
|
18223
18223
|
if ("svg" === b2 ? o3 = "http://www.w3.org/2000/svg" : "math" === b2 ? o3 = "http://www.w3.org/1998/Math/MathML" : o3 || (o3 = "http://www.w3.org/1999/xhtml"), null != r3) {
|
|
18224
18224
|
for (s3 = 0; s3 < r3.length; s3++) if ((d3 = r3[s3]) && "setAttribute" in d3 == !!b2 && (b2 ? d3.localName === b2 : 3 === d3.nodeType)) {
|
|
18225
18225
|
l3 = d3, r3[s3] = null;
|
|
@@ -18232,7 +18232,7 @@ function z(l3, u3, t4, i3, o3, r3, f3, e3, c3) {
|
|
|
18232
18232
|
}
|
|
18233
18233
|
if (null === b2) m2 === k3 || e3 && l3.data === k3 || (l3.data = k3);
|
|
18234
18234
|
else {
|
|
18235
|
-
if (r3 = r3 && n2.call(l3.childNodes), m2 =
|
|
18235
|
+
if (r3 = r3 && n2.call(l3.childNodes), m2 = t5.props || h, !e3 && null != r3) for (m2 = {}, s3 = 0; s3 < l3.attributes.length; s3++) m2[(d3 = l3.attributes[s3]).name] = d3.value;
|
|
18236
18236
|
for (s3 in m2) if (d3 = m2[s3], "children" == s3) ;
|
|
18237
18237
|
else if ("dangerouslySetInnerHTML" == s3) p3 = d3;
|
|
18238
18238
|
else if ("key" !== s3 && !(s3 in k3)) {
|
|
@@ -18241,19 +18241,19 @@ function z(l3, u3, t4, i3, o3, r3, f3, e3, c3) {
|
|
|
18241
18241
|
}
|
|
18242
18242
|
for (s3 in k3) d3 = k3[s3], "children" == s3 ? v3 = d3 : "dangerouslySetInnerHTML" == s3 ? a3 = d3 : "value" == s3 ? _4 = d3 : "checked" == s3 ? g2 = d3 : "key" === s3 || e3 && "function" != typeof d3 || m2[s3] === d3 || A(l3, s3, d3, m2[s3], o3);
|
|
18243
18243
|
if (a3) e3 || p3 && (a3.__html === p3.__html || a3.__html === l3.innerHTML) || (l3.innerHTML = a3.__html), u3.__k = [];
|
|
18244
|
-
else if (p3 && (l3.innerHTML = ""), S(l3, y(v3) ? v3 : [v3], u3,
|
|
18244
|
+
else if (p3 && (l3.innerHTML = ""), S(l3, y(v3) ? v3 : [v3], u3, t5, i3, "foreignObject" === b2 ? "http://www.w3.org/1999/xhtml" : o3, r3, f3, r3 ? r3[0] : t5.__k && x(t5, 0), e3, c3), null != r3) for (s3 = r3.length; s3--; ) null != r3[s3] && w(r3[s3]);
|
|
18245
18245
|
e3 || (s3 = "value", void 0 !== _4 && (_4 !== l3[s3] || "progress" === b2 && !_4 || "option" === b2 && _4 !== m2[s3]) && A(l3, s3, _4, m2[s3], o3), s3 = "checked", void 0 !== g2 && g2 !== l3[s3] && A(l3, s3, g2, m2[s3], o3));
|
|
18246
18246
|
}
|
|
18247
18247
|
return l3;
|
|
18248
18248
|
}
|
|
18249
|
-
function N(n3, u3,
|
|
18249
|
+
function N(n3, u3, t5) {
|
|
18250
18250
|
try {
|
|
18251
18251
|
"function" == typeof n3 ? n3(u3) : n3.current = u3;
|
|
18252
18252
|
} catch (n4) {
|
|
18253
|
-
l.__e(n4,
|
|
18253
|
+
l.__e(n4, t5);
|
|
18254
18254
|
}
|
|
18255
18255
|
}
|
|
18256
|
-
function V(n3, u3,
|
|
18256
|
+
function V(n3, u3, t5) {
|
|
18257
18257
|
var i3, o3;
|
|
18258
18258
|
if (l.unmount && l.unmount(n3), (i3 = n3.ref) && (i3.current && i3.current !== n3.__e || N(i3, null, u3)), null != (i3 = n3.__c)) {
|
|
18259
18259
|
if (i3.componentWillUnmount) try {
|
|
@@ -18263,19 +18263,19 @@ function V(n3, u3, t4) {
|
|
|
18263
18263
|
}
|
|
18264
18264
|
i3.base = i3.__P = null;
|
|
18265
18265
|
}
|
|
18266
|
-
if (i3 = n3.__k) for (o3 = 0; o3 < i3.length; o3++) i3[o3] && V(i3[o3], u3,
|
|
18267
|
-
|
|
18266
|
+
if (i3 = n3.__k) for (o3 = 0; o3 < i3.length; o3++) i3[o3] && V(i3[o3], u3, t5 || "function" != typeof n3.type);
|
|
18267
|
+
t5 || null == n3.__e || w(n3.__e), n3.__c = n3.__ = n3.__e = n3.__d = void 0;
|
|
18268
18268
|
}
|
|
18269
18269
|
function q(n3, l3, u3) {
|
|
18270
18270
|
return this.constructor(n3, u3);
|
|
18271
18271
|
}
|
|
18272
|
-
function B(u3,
|
|
18272
|
+
function B(u3, t5, i3) {
|
|
18273
18273
|
var o3, r3, f3, e3;
|
|
18274
|
-
l.__ && l.__(u3,
|
|
18274
|
+
l.__ && l.__(u3, t5), r3 = (o3 = "function" == typeof i3) ? null : i3 && i3.__k || t5.__k, f3 = [], e3 = [], O(t5, u3 = (!o3 && i3 || t5).__k = _(k, null, [u3]), r3 || h, h, t5.namespaceURI, !o3 && i3 ? [i3] : r3 ? null : t5.firstChild ? n2.call(t5.childNodes) : null, f3, !o3 && i3 ? i3 : r3 ? r3.__e : t5.firstChild, o3, e3), j(f3, u3, e3);
|
|
18275
18275
|
}
|
|
18276
|
-
n2 = p.slice, l = { __e: function(n3, l3, u3,
|
|
18276
|
+
n2 = p.slice, l = { __e: function(n3, l3, u3, t5) {
|
|
18277
18277
|
for (var i3, o3, r3; l3 = l3.__; ) if ((i3 = l3.__c) && !i3.__) try {
|
|
18278
|
-
if ((o3 = i3.constructor) && null != o3.getDerivedStateFromError && (i3.setState(o3.getDerivedStateFromError(n3)), r3 = i3.__d), null != i3.componentDidCatch && (i3.componentDidCatch(n3,
|
|
18278
|
+
if ((o3 = i3.constructor) && null != o3.getDerivedStateFromError && (i3.setState(o3.getDerivedStateFromError(n3)), r3 = i3.__d), null != i3.componentDidCatch && (i3.componentDidCatch(n3, t5 || {}), r3 = i3.__d), r3) return i3.__E = i3;
|
|
18279
18279
|
} catch (l4) {
|
|
18280
18280
|
n3 = l4;
|
|
18281
18281
|
}
|
|
@@ -18306,8 +18306,8 @@ var l2 = e2.diffed;
|
|
|
18306
18306
|
var m = e2.__c;
|
|
18307
18307
|
var s2 = e2.unmount;
|
|
18308
18308
|
var d2 = e2.__;
|
|
18309
|
-
function h2(n3,
|
|
18310
|
-
e2.__h && e2.__h(r2, n3, o2 ||
|
|
18309
|
+
function h2(n3, t5) {
|
|
18310
|
+
e2.__h && e2.__h(r2, n3, o2 || t5), o2 = 0;
|
|
18311
18311
|
var u3 = r2.__H || (r2.__H = { __: [], __h: [] });
|
|
18312
18312
|
return n3 >= u3.__.length && u3.__.push({ __V: c2 }), u3.__[n3];
|
|
18313
18313
|
}
|
|
@@ -18317,33 +18317,33 @@ function p2(n3) {
|
|
|
18317
18317
|
function y2(n3, u3, i3) {
|
|
18318
18318
|
var o3 = h2(t3++, 2);
|
|
18319
18319
|
if (o3.t = n3, !o3.__c && (o3.__ = [i3 ? i3(u3) : D(void 0, u3), function(n4) {
|
|
18320
|
-
var
|
|
18321
|
-
|
|
18320
|
+
var t5 = o3.__N ? o3.__N[0] : o3.__[0], r3 = o3.t(t5, n4);
|
|
18321
|
+
t5 !== r3 && (o3.__N = [r3, o3.__[1]], o3.__c.setState({}));
|
|
18322
18322
|
}], o3.__c = r2, !r2.u)) {
|
|
18323
|
-
var f3 = function(n4,
|
|
18323
|
+
var f3 = function(n4, t5, r3) {
|
|
18324
18324
|
if (!o3.__c.__H) return true;
|
|
18325
18325
|
var u4 = o3.__c.__H.__.filter(function(n5) {
|
|
18326
18326
|
return !!n5.__c;
|
|
18327
18327
|
});
|
|
18328
18328
|
if (u4.every(function(n5) {
|
|
18329
18329
|
return !n5.__N;
|
|
18330
|
-
})) return !c3 || c3.call(this, n4,
|
|
18330
|
+
})) return !c3 || c3.call(this, n4, t5, r3);
|
|
18331
18331
|
var i4 = false;
|
|
18332
18332
|
return u4.forEach(function(n5) {
|
|
18333
18333
|
if (n5.__N) {
|
|
18334
|
-
var
|
|
18335
|
-
n5.__ = n5.__N, n5.__N = void 0,
|
|
18334
|
+
var t6 = n5.__[0];
|
|
18335
|
+
n5.__ = n5.__N, n5.__N = void 0, t6 !== n5.__[0] && (i4 = true);
|
|
18336
18336
|
}
|
|
18337
|
-
}), !(!i4 && o3.__c.props === n4) && (!c3 || c3.call(this, n4,
|
|
18337
|
+
}), !(!i4 && o3.__c.props === n4) && (!c3 || c3.call(this, n4, t5, r3));
|
|
18338
18338
|
};
|
|
18339
18339
|
r2.u = true;
|
|
18340
18340
|
var c3 = r2.shouldComponentUpdate, e3 = r2.componentWillUpdate;
|
|
18341
|
-
r2.componentWillUpdate = function(n4,
|
|
18341
|
+
r2.componentWillUpdate = function(n4, t5, r3) {
|
|
18342
18342
|
if (this.__e) {
|
|
18343
18343
|
var u4 = c3;
|
|
18344
|
-
c3 = void 0, f3(n4,
|
|
18344
|
+
c3 = void 0, f3(n4, t5, r3), c3 = u4;
|
|
18345
18345
|
}
|
|
18346
|
-
e3 && e3.call(this, n4,
|
|
18346
|
+
e3 && e3.call(this, n4, t5, r3);
|
|
18347
18347
|
}, r2.shouldComponentUpdate = f3;
|
|
18348
18348
|
}
|
|
18349
18349
|
return o3.__N || o3.__;
|
|
@@ -18361,22 +18361,22 @@ function q2(n3, r3) {
|
|
|
18361
18361
|
var u3 = h2(t3++, 7);
|
|
18362
18362
|
return C2(u3.__H, r3) ? (u3.__V = n3(), u3.i = r3, u3.__h = n3, u3.__V) : u3.__;
|
|
18363
18363
|
}
|
|
18364
|
-
function x2(n3,
|
|
18364
|
+
function x2(n3, t5) {
|
|
18365
18365
|
return o2 = 8, q2(function() {
|
|
18366
18366
|
return n3;
|
|
18367
|
-
},
|
|
18367
|
+
}, t5);
|
|
18368
18368
|
}
|
|
18369
18369
|
function j2() {
|
|
18370
18370
|
for (var n3; n3 = f2.shift(); ) if (n3.__P && n3.__H) try {
|
|
18371
18371
|
n3.__H.__h.forEach(z2), n3.__H.__h.forEach(B2), n3.__H.__h = [];
|
|
18372
|
-
} catch (
|
|
18373
|
-
n3.__H.__h = [], e2.__e(
|
|
18372
|
+
} catch (t5) {
|
|
18373
|
+
n3.__H.__h = [], e2.__e(t5, n3.__v);
|
|
18374
18374
|
}
|
|
18375
18375
|
}
|
|
18376
18376
|
e2.__b = function(n3) {
|
|
18377
18377
|
r2 = null, a2 && a2(n3);
|
|
18378
|
-
}, e2.__ = function(n3,
|
|
18379
|
-
n3 &&
|
|
18378
|
+
}, e2.__ = function(n3, t5) {
|
|
18379
|
+
n3 && t5.__k && t5.__k.__m && (n3.__m = t5.__k.__m), d2 && d2(n3, t5);
|
|
18380
18380
|
}, e2.__r = function(n3) {
|
|
18381
18381
|
v2 && v2(n3), t3 = 0;
|
|
18382
18382
|
var i3 = (r2 = n3.__c).__H;
|
|
@@ -18385,55 +18385,55 @@ e2.__b = function(n3) {
|
|
|
18385
18385
|
})) : (i3.__h.forEach(z2), i3.__h.forEach(B2), i3.__h = [], t3 = 0)), u2 = r2;
|
|
18386
18386
|
}, e2.diffed = function(n3) {
|
|
18387
18387
|
l2 && l2(n3);
|
|
18388
|
-
var
|
|
18389
|
-
|
|
18388
|
+
var t5 = n3.__c;
|
|
18389
|
+
t5 && t5.__H && (t5.__H.__h.length && (1 !== f2.push(t5) && i2 === e2.requestAnimationFrame || ((i2 = e2.requestAnimationFrame) || w2)(j2)), t5.__H.__.forEach(function(n4) {
|
|
18390
18390
|
n4.i && (n4.__H = n4.i), n4.__V !== c2 && (n4.__ = n4.__V), n4.i = void 0, n4.__V = c2;
|
|
18391
18391
|
})), u2 = r2 = null;
|
|
18392
|
-
}, e2.__c = function(n3,
|
|
18393
|
-
|
|
18392
|
+
}, e2.__c = function(n3, t5) {
|
|
18393
|
+
t5.some(function(n4) {
|
|
18394
18394
|
try {
|
|
18395
18395
|
n4.__h.forEach(z2), n4.__h = n4.__h.filter(function(n5) {
|
|
18396
18396
|
return !n5.__ || B2(n5);
|
|
18397
18397
|
});
|
|
18398
18398
|
} catch (r3) {
|
|
18399
|
-
|
|
18399
|
+
t5.some(function(n5) {
|
|
18400
18400
|
n5.__h && (n5.__h = []);
|
|
18401
|
-
}),
|
|
18401
|
+
}), t5 = [], e2.__e(r3, n4.__v);
|
|
18402
18402
|
}
|
|
18403
|
-
}), m && m(n3,
|
|
18403
|
+
}), m && m(n3, t5);
|
|
18404
18404
|
}, e2.unmount = function(n3) {
|
|
18405
18405
|
s2 && s2(n3);
|
|
18406
|
-
var
|
|
18406
|
+
var t5, r3 = n3.__c;
|
|
18407
18407
|
r3 && r3.__H && (r3.__H.__.forEach(function(n4) {
|
|
18408
18408
|
try {
|
|
18409
18409
|
z2(n4);
|
|
18410
18410
|
} catch (n5) {
|
|
18411
|
-
|
|
18411
|
+
t5 = n5;
|
|
18412
18412
|
}
|
|
18413
|
-
}), r3.__H = void 0,
|
|
18413
|
+
}), r3.__H = void 0, t5 && e2.__e(t5, r3.__v));
|
|
18414
18414
|
};
|
|
18415
18415
|
var k2 = "function" == typeof requestAnimationFrame;
|
|
18416
18416
|
function w2(n3) {
|
|
18417
|
-
var
|
|
18418
|
-
clearTimeout(u3), k2 && cancelAnimationFrame(
|
|
18417
|
+
var t5, r3 = function() {
|
|
18418
|
+
clearTimeout(u3), k2 && cancelAnimationFrame(t5), setTimeout(n3);
|
|
18419
18419
|
}, u3 = setTimeout(r3, 100);
|
|
18420
|
-
k2 && (
|
|
18420
|
+
k2 && (t5 = requestAnimationFrame(r3));
|
|
18421
18421
|
}
|
|
18422
18422
|
function z2(n3) {
|
|
18423
|
-
var
|
|
18424
|
-
"function" == typeof u3 && (n3.__c = void 0, u3()), r2 =
|
|
18423
|
+
var t5 = r2, u3 = n3.__c;
|
|
18424
|
+
"function" == typeof u3 && (n3.__c = void 0, u3()), r2 = t5;
|
|
18425
18425
|
}
|
|
18426
18426
|
function B2(n3) {
|
|
18427
|
-
var
|
|
18428
|
-
n3.__c = n3.__(), r2 =
|
|
18427
|
+
var t5 = r2;
|
|
18428
|
+
n3.__c = n3.__(), r2 = t5;
|
|
18429
18429
|
}
|
|
18430
|
-
function C2(n3,
|
|
18431
|
-
return !n3 || n3.length !==
|
|
18432
|
-
return
|
|
18430
|
+
function C2(n3, t5) {
|
|
18431
|
+
return !n3 || n3.length !== t5.length || t5.some(function(t6, r3) {
|
|
18432
|
+
return t6 !== n3[r3];
|
|
18433
18433
|
});
|
|
18434
18434
|
}
|
|
18435
|
-
function D(n3,
|
|
18436
|
-
return "function" == typeof
|
|
18435
|
+
function D(n3, t5) {
|
|
18436
|
+
return "function" == typeof t5 ? t5(n3) : t5;
|
|
18437
18437
|
}
|
|
18438
18438
|
|
|
18439
18439
|
// dashboard/src/lib/api.ts
|
|
@@ -18493,9 +18493,9 @@ function ToastStack() {
|
|
|
18493
18493
|
const onToast = (ev) => {
|
|
18494
18494
|
const detail = ev.detail;
|
|
18495
18495
|
const id = `${Date.now()}-${Math.random()}`;
|
|
18496
|
-
const
|
|
18497
|
-
setToasts((prev) => [...prev,
|
|
18498
|
-
setTimeout(() => setToasts((prev) => prev.filter((x3) => x3.id !== id)),
|
|
18496
|
+
const t5 = { id, ...detail };
|
|
18497
|
+
setToasts((prev) => [...prev, t5]);
|
|
18498
|
+
setTimeout(() => setToasts((prev) => prev.filter((x3) => x3.id !== id)), t5.ttl);
|
|
18499
18499
|
};
|
|
18500
18500
|
toastBus.addEventListener("toast", onToast);
|
|
18501
18501
|
return () => toastBus.removeEventListener("toast", onToast);
|
|
@@ -18503,7 +18503,7 @@ function ToastStack() {
|
|
|
18503
18503
|
if (toasts.length === 0) return null;
|
|
18504
18504
|
return html`
|
|
18505
18505
|
<div class="toast-stack">
|
|
18506
|
-
${toasts.map((
|
|
18506
|
+
${toasts.map((t5) => html`<div key=${t5.id} class="toast ${t5.kind}">${t5.text}</div>`)}
|
|
18507
18507
|
</div>
|
|
18508
18508
|
`;
|
|
18509
18509
|
}
|
|
@@ -18636,6 +18636,1094 @@ var ErrorBoundary = class extends b {
|
|
|
18636
18636
|
}
|
|
18637
18637
|
};
|
|
18638
18638
|
|
|
18639
|
+
// dashboard/src/lib/i18n.ts
|
|
18640
|
+
var LANG_REGISTRY = [
|
|
18641
|
+
["en", "EN"],
|
|
18642
|
+
["zh-CN", "zh-CN"]
|
|
18643
|
+
];
|
|
18644
|
+
var SUPPORTED = new Set(LANG_REGISTRY.map(([d3]) => d3));
|
|
18645
|
+
var TO_BACKEND = new Map(LANG_REGISTRY);
|
|
18646
|
+
var FROM_BACKEND = new Map(LANG_REGISTRY.map(([d3, b2]) => [b2, d3]));
|
|
18647
|
+
var STORAGE_KEY = "rx.lang";
|
|
18648
|
+
var EXPLICIT_KEY = "rx.langExplicit";
|
|
18649
|
+
var listeners = [];
|
|
18650
|
+
var currentLang = loadFromStorage() ?? "en";
|
|
18651
|
+
function loadFromStorage() {
|
|
18652
|
+
try {
|
|
18653
|
+
const v3 = localStorage.getItem(STORAGE_KEY);
|
|
18654
|
+
if (v3 !== null && SUPPORTED.has(v3)) return v3;
|
|
18655
|
+
} catch {
|
|
18656
|
+
}
|
|
18657
|
+
return null;
|
|
18658
|
+
}
|
|
18659
|
+
function isExplicit() {
|
|
18660
|
+
try {
|
|
18661
|
+
return localStorage.getItem(EXPLICIT_KEY) === "1";
|
|
18662
|
+
} catch {
|
|
18663
|
+
return false;
|
|
18664
|
+
}
|
|
18665
|
+
}
|
|
18666
|
+
function markExplicit() {
|
|
18667
|
+
try {
|
|
18668
|
+
localStorage.setItem(EXPLICIT_KEY, "1");
|
|
18669
|
+
} catch {
|
|
18670
|
+
}
|
|
18671
|
+
}
|
|
18672
|
+
function toBackendLang(lang) {
|
|
18673
|
+
return TO_BACKEND.get(lang) ?? lang;
|
|
18674
|
+
}
|
|
18675
|
+
function fromBackendLang(raw) {
|
|
18676
|
+
return FROM_BACKEND.get(raw) ?? "en";
|
|
18677
|
+
}
|
|
18678
|
+
async function initLangFromServer() {
|
|
18679
|
+
try {
|
|
18680
|
+
const stored = loadFromStorage();
|
|
18681
|
+
const res = await api("/settings");
|
|
18682
|
+
const serverLang = res.lang ? fromBackendLang(res.lang) : null;
|
|
18683
|
+
if (!serverLang || stored === serverLang) return;
|
|
18684
|
+
if (isExplicit() && stored) {
|
|
18685
|
+
api("/settings", { method: "POST", body: { lang: toBackendLang(stored) } }).catch((err) => console.error("[reasonix dashboard] lang sync:", err));
|
|
18686
|
+
return;
|
|
18687
|
+
}
|
|
18688
|
+
currentLang = serverLang;
|
|
18689
|
+
try {
|
|
18690
|
+
localStorage.setItem(STORAGE_KEY, serverLang);
|
|
18691
|
+
} catch {
|
|
18692
|
+
}
|
|
18693
|
+
for (const cb of listeners) cb();
|
|
18694
|
+
} catch {
|
|
18695
|
+
}
|
|
18696
|
+
}
|
|
18697
|
+
function getLang() {
|
|
18698
|
+
return currentLang;
|
|
18699
|
+
}
|
|
18700
|
+
function setLang(lang) {
|
|
18701
|
+
if (!SUPPORTED.has(lang)) return;
|
|
18702
|
+
currentLang = lang;
|
|
18703
|
+
markExplicit();
|
|
18704
|
+
try {
|
|
18705
|
+
localStorage.setItem(STORAGE_KEY, lang);
|
|
18706
|
+
} catch {
|
|
18707
|
+
}
|
|
18708
|
+
for (const cb of listeners) cb();
|
|
18709
|
+
fetch(`/api/settings?token=${TOKEN}`, {
|
|
18710
|
+
method: "POST",
|
|
18711
|
+
headers: { "Content-Type": "application/json", "X-Reasonix-Token": TOKEN },
|
|
18712
|
+
body: JSON.stringify({ lang: toBackendLang(lang) }),
|
|
18713
|
+
keepalive: true
|
|
18714
|
+
}).catch((err) => console.error("[reasonix dashboard] lang persist:", err));
|
|
18715
|
+
}
|
|
18716
|
+
function onLangChange(cb) {
|
|
18717
|
+
listeners.push(cb);
|
|
18718
|
+
return () => {
|
|
18719
|
+
const i3 = listeners.indexOf(cb);
|
|
18720
|
+
if (i3 >= 0) listeners.splice(i3, 1);
|
|
18721
|
+
};
|
|
18722
|
+
}
|
|
18723
|
+
function useLang() {
|
|
18724
|
+
const [lang, setLangState] = p2(currentLang);
|
|
18725
|
+
_2(() => onLangChange(() => setLangState(currentLang)), []);
|
|
18726
|
+
return lang;
|
|
18727
|
+
}
|
|
18728
|
+
function get(translations, path) {
|
|
18729
|
+
let val = translations;
|
|
18730
|
+
for (const part of path.split(".")) {
|
|
18731
|
+
if (val === void 0 || typeof val === "string") return void 0;
|
|
18732
|
+
val = val[part];
|
|
18733
|
+
}
|
|
18734
|
+
return typeof val === "string" ? val : void 0;
|
|
18735
|
+
}
|
|
18736
|
+
function createT(translations) {
|
|
18737
|
+
return function t5(path, params) {
|
|
18738
|
+
let val = get(translations[currentLang] ?? translations.en, path);
|
|
18739
|
+
if (val === void 0) val = get(translations.en, path);
|
|
18740
|
+
if (val === void 0) return path;
|
|
18741
|
+
if (!params) return val;
|
|
18742
|
+
let result = val;
|
|
18743
|
+
for (const [k3, v3] of Object.entries(params)) {
|
|
18744
|
+
result = result.replaceAll(`{${k3}}`, String(v3));
|
|
18745
|
+
}
|
|
18746
|
+
return result;
|
|
18747
|
+
};
|
|
18748
|
+
}
|
|
18749
|
+
|
|
18750
|
+
// dashboard/src/i18n/en.ts
|
|
18751
|
+
var en = {
|
|
18752
|
+
app: {
|
|
18753
|
+
sectionWorkspace: "workspace",
|
|
18754
|
+
sectionObserve: "observe",
|
|
18755
|
+
sectionConfigure: "configure",
|
|
18756
|
+
tabChat: "Chat",
|
|
18757
|
+
tabPlans: "Plans",
|
|
18758
|
+
tabSessions: "Sessions",
|
|
18759
|
+
tabOverview: "Overview",
|
|
18760
|
+
tabUsage: "Usage",
|
|
18761
|
+
tabSystem: "System",
|
|
18762
|
+
tabSemantic: "Semantic",
|
|
18763
|
+
tabTools: "Tools",
|
|
18764
|
+
tabPermissions: "Permissions",
|
|
18765
|
+
tabMcp: "MCP",
|
|
18766
|
+
tabSkills: "Skills",
|
|
18767
|
+
tabMemory: "Memory",
|
|
18768
|
+
tabHooks: "Hooks",
|
|
18769
|
+
tabSettings: "Settings",
|
|
18770
|
+
footer: "127.0.0.1 only \xB7 token-gated"
|
|
18771
|
+
},
|
|
18772
|
+
common: {
|
|
18773
|
+
loading: "loading\u2026",
|
|
18774
|
+
loadingFailed: "{name} failed: {error}",
|
|
18775
|
+
back: "\u2190 back",
|
|
18776
|
+
save: "Save",
|
|
18777
|
+
remove: "remove",
|
|
18778
|
+
cancel: "Cancel",
|
|
18779
|
+
delete: "Delete",
|
|
18780
|
+
add: "Add",
|
|
18781
|
+
confirm: "Confirm",
|
|
18782
|
+
noData: "No {name} yet.",
|
|
18783
|
+
all: "all",
|
|
18784
|
+
yes: "yes",
|
|
18785
|
+
no: "no",
|
|
18786
|
+
on: "ON",
|
|
18787
|
+
off: "off",
|
|
18788
|
+
enabled: "enabled",
|
|
18789
|
+
disabled: "disabled"
|
|
18790
|
+
},
|
|
18791
|
+
settings: {
|
|
18792
|
+
title: "Settings",
|
|
18793
|
+
loading: "loading settings\u2026",
|
|
18794
|
+
saved: "saved: {fields}",
|
|
18795
|
+
sectionApi: "DeepSeek API",
|
|
18796
|
+
apiKey: "API key",
|
|
18797
|
+
notSet: "(not set)",
|
|
18798
|
+
replace: "replace",
|
|
18799
|
+
pasteKey: "paste a fresh sk-\u2026 token",
|
|
18800
|
+
saveKey: "Save key",
|
|
18801
|
+
baseUrl: "base url",
|
|
18802
|
+
baseUrlPlaceholder: "https://api.deepseek.com (default)",
|
|
18803
|
+
sectionDefaults: "Defaults",
|
|
18804
|
+
preset: "preset",
|
|
18805
|
+
presetAuto: "auto \u2014 flash \u2192 pro on hard turns",
|
|
18806
|
+
presetFlash: "flash \u2014 always flash, no auto-escalate",
|
|
18807
|
+
presetPro: "pro \u2014 always pro",
|
|
18808
|
+
appliesNextTurn: "applies next turn",
|
|
18809
|
+
effort: "effort",
|
|
18810
|
+
effortMax: "max (default \u2014 best)",
|
|
18811
|
+
effortHigh: "high (cheaper / faster)",
|
|
18812
|
+
webSearch: "web search",
|
|
18813
|
+
webSearchNote: "web_fetch + web_search tools",
|
|
18814
|
+
sectionRuntime: "Runtime",
|
|
18815
|
+
activeModel: "active model",
|
|
18816
|
+
editMode: "edit mode",
|
|
18817
|
+
editModeNote: "switch from the Chat tab header",
|
|
18818
|
+
sectionLanguage: "Language",
|
|
18819
|
+
language: "language",
|
|
18820
|
+
langEn: "English",
|
|
18821
|
+
langZhCn: "\u7B80\u4F53\u4E2D\u6587"
|
|
18822
|
+
},
|
|
18823
|
+
chat: {
|
|
18824
|
+
modeMirror: "TUI mirror",
|
|
18825
|
+
modeView: "session view",
|
|
18826
|
+
placeholder: "Type a prompt \u2014 Enter sends, Shift+Enter for a newline \xB7 / @ for pickers",
|
|
18827
|
+
placeholderBusy: "wait for the current turn to finish\u2026",
|
|
18828
|
+
send: "Send",
|
|
18829
|
+
new: "New",
|
|
18830
|
+
clear: "Clear",
|
|
18831
|
+
newTitle: "/new \u2014 wipe conversation context (loop log + scrollback)",
|
|
18832
|
+
clearTitle: "/clear \u2014 wipe just visible scrollback (context kept)",
|
|
18833
|
+
noConversation: "No conversation yet. Send a prompt below to begin.",
|
|
18834
|
+
newConfirmBusy: "A turn is in flight. Abort and start a new conversation?",
|
|
18835
|
+
newConfirm: "Clear current conversation and start fresh?",
|
|
18836
|
+
newToast: "new conversation",
|
|
18837
|
+
clearToast: "scrollback cleared",
|
|
18838
|
+
newFailed: "/new failed: {error}",
|
|
18839
|
+
clearFailed: "/clear failed: {error}",
|
|
18840
|
+
eventStreamError: "event stream interrupted \u2014 reconnecting\u2026",
|
|
18841
|
+
semanticBanner: "Semantic search isn't enabled for this project.",
|
|
18842
|
+
semanticBannerDesc: 'Build the index once and the model can find code by meaning ("where do we handle auth failures?") instead of grep on exact strings.',
|
|
18843
|
+
semanticBannerBtn: "Build it \u2192",
|
|
18844
|
+
semanticBannerDismiss: "dismiss (don't show again)",
|
|
18845
|
+
slashCommands: "slash commands",
|
|
18846
|
+
projectFiles: "project files",
|
|
18847
|
+
effortTitle: "reasoning_effort \u2014 applies next turn",
|
|
18848
|
+
effortMaxTitle: "max (default \u2014 best quality)",
|
|
18849
|
+
effortHighTitle: "high (cheaper / faster)",
|
|
18850
|
+
presetTitle: "preset \u2014 model commitment",
|
|
18851
|
+
presetAutoTitle: "auto \u2014 flash baseline; auto-escalates to pro on hard turns (NEEDS_PRO / failure threshold)",
|
|
18852
|
+
presetFlashTitle: "flash \u2014 always flash; no auto-escalate. /pro still works for one-shot manual",
|
|
18853
|
+
presetProTitle: "pro \u2014 always pro; ~3\xD7 flash cost (5/31 discount). Locks in on hard architecture work.",
|
|
18854
|
+
editGateTitle: "edit gate \u2014 Shift+Tab cycles in TUI",
|
|
18855
|
+
editReviewTitle: "review \u2014 both edits and non-allowlisted shell ask first",
|
|
18856
|
+
editAutoTitle: "auto \u2014 edits auto-apply, shell still asks",
|
|
18857
|
+
editYoloTitle: "yolo \u2014 edits AND shell auto-run, allowlist bypassed",
|
|
18858
|
+
railSession: "Session",
|
|
18859
|
+
railTurns: "turns",
|
|
18860
|
+
railPromptTok: "prompt tok",
|
|
18861
|
+
railCost: "cost",
|
|
18862
|
+
railCacheHit: "cache hit",
|
|
18863
|
+
railToolBudget: "Tool budget",
|
|
18864
|
+
railSpend: "spend",
|
|
18865
|
+
railActivePlan: "Active plan",
|
|
18866
|
+
railProgress: "progress",
|
|
18867
|
+
statusModel: "model",
|
|
18868
|
+
statusCtx: "ctx",
|
|
18869
|
+
statusCache: "cache",
|
|
18870
|
+
statusTurn: "turn",
|
|
18871
|
+
statusSession: "session",
|
|
18872
|
+
statusBalance: "balance",
|
|
18873
|
+
statusTurns: "{count} turn{s}",
|
|
18874
|
+
waitingStats: "\xB7 \xB7 \xB7 waiting for live stats",
|
|
18875
|
+
inflightPhase: "{phase}",
|
|
18876
|
+
inflightRunning: "running",
|
|
18877
|
+
inflightThinking: "thinking",
|
|
18878
|
+
inflightStreaming: "streaming",
|
|
18879
|
+
inflightWaiting: "waiting",
|
|
18880
|
+
inflightReasoning: "reasoning {count} ch",
|
|
18881
|
+
inflightOut: "out {count} ch",
|
|
18882
|
+
abortBtn: "Abort (Esc)",
|
|
18883
|
+
confirmBtn: "Apply (y)",
|
|
18884
|
+
rejectBtn: "Reject (n)",
|
|
18885
|
+
applyRestBtn: "Apply rest (a)",
|
|
18886
|
+
flipAutoBtn: "Flip to AUTO (A)"
|
|
18887
|
+
},
|
|
18888
|
+
overview: {
|
|
18889
|
+
loading: "loading overview\u2026",
|
|
18890
|
+
failed: "overview failed: {error}",
|
|
18891
|
+
standaloneTitle: "Standalone mode",
|
|
18892
|
+
standaloneDesc: "Read-only disk view. Start /dashboard from inside reasonix code for live session state, MCP, and tools.",
|
|
18893
|
+
cockpit: "Cockpit",
|
|
18894
|
+
balance: "balance",
|
|
18895
|
+
tokens7d: "tokens \xB7 7d",
|
|
18896
|
+
cacheHit: "cache hit",
|
|
18897
|
+
toolCalls24h: "tool calls \xB7 24h",
|
|
18898
|
+
currentSession: "current session",
|
|
18899
|
+
noSession: "No live session \u2014 /dashboard from inside reasonix code to attach.",
|
|
18900
|
+
promptTok: "prompt tok",
|
|
18901
|
+
completionTok: "completion tok",
|
|
18902
|
+
cost: "cost",
|
|
18903
|
+
costTrend: "cost \xB7 14 day",
|
|
18904
|
+
noUsageYet: "no usage yet",
|
|
18905
|
+
dayAvg: "/day avg",
|
|
18906
|
+
recentPlans: "recent plans",
|
|
18907
|
+
noPlans: "No plans yet \u2014 submit one with submit_plan.",
|
|
18908
|
+
toolActivity: "tool activity",
|
|
18909
|
+
noToolCalls: "No tool calls yet.",
|
|
18910
|
+
toolsLoaded: "tools loaded",
|
|
18911
|
+
mcpServers: "mcp servers",
|
|
18912
|
+
editMode: "edit mode",
|
|
18913
|
+
version: "Reasonix",
|
|
18914
|
+
workingDir: "Working directory",
|
|
18915
|
+
projectRoot: "project root",
|
|
18916
|
+
noPriorData: "no prior data",
|
|
18917
|
+
stable: "\u2014 stable",
|
|
18918
|
+
vsPrior: "{arrow} {pct}% vs prior",
|
|
18919
|
+
active: "active",
|
|
18920
|
+
allUp: "all up",
|
|
18921
|
+
yoloWarning: "all prompts bypassed",
|
|
18922
|
+
checking: "checking",
|
|
18923
|
+
latest: "latest"
|
|
18924
|
+
},
|
|
18925
|
+
usage: {
|
|
18926
|
+
loading: "loading usage\u2026",
|
|
18927
|
+
failed: "usage failed: {error}",
|
|
18928
|
+
records: "{count} records",
|
|
18929
|
+
dailyUsage: "Daily usage",
|
|
18930
|
+
dailyMeta: "cost \xB7 cache saved \xB7 turns",
|
|
18931
|
+
noData: "No usage data yet \u2014 run a turn in reasonix chat / code / run and refresh.",
|
|
18932
|
+
windows: "Rolling windows",
|
|
18933
|
+
colTurns: "turns",
|
|
18934
|
+
colCacheHit: "cache hit",
|
|
18935
|
+
colCost: "cost (USD)",
|
|
18936
|
+
colCacheSaved: "cache saved",
|
|
18937
|
+
colVsClaude: "vs Claude",
|
|
18938
|
+
colSaved: "saved",
|
|
18939
|
+
mostUsed: "Most used models",
|
|
18940
|
+
colModel: "model"
|
|
18941
|
+
},
|
|
18942
|
+
sessions: {
|
|
18943
|
+
loading: "loading sessions\u2026",
|
|
18944
|
+
failed: "sessions failed: {error}",
|
|
18945
|
+
noSessions: "No saved sessions yet.",
|
|
18946
|
+
filterPlaceholder: "filter sessions",
|
|
18947
|
+
msgs: "msgs",
|
|
18948
|
+
pickHint: "Pick a session on the left to read its transcript.",
|
|
18949
|
+
resumeTitle: "Resume in TUI",
|
|
18950
|
+
resumeDesc: "Mid-session swap requires a restart so the message log can rewind cleanly. Quit your current session, then run:",
|
|
18951
|
+
loadingTranscript: "loading transcript\u2026",
|
|
18952
|
+
emptyTranscript: "empty transcript.",
|
|
18953
|
+
messages: "{count} message{s}"
|
|
18954
|
+
},
|
|
18955
|
+
tools: {
|
|
18956
|
+
loading: "loading tools\u2026",
|
|
18957
|
+
failed: "tools failed: {error}",
|
|
18958
|
+
noTools: "No tools registered.",
|
|
18959
|
+
planMode: "plan mode \u2014 writes gated",
|
|
18960
|
+
colTool: "tool",
|
|
18961
|
+
colFlags: "flags",
|
|
18962
|
+
colDesc: "description",
|
|
18963
|
+
readOnly: "read-only",
|
|
18964
|
+
write: "write",
|
|
18965
|
+
flat: "flat"
|
|
18966
|
+
},
|
|
18967
|
+
permissions: {
|
|
18968
|
+
loading: "loading permissions\u2026",
|
|
18969
|
+
failed: "permissions failed: {error}",
|
|
18970
|
+
yoloTitle: "YOLO mode",
|
|
18971
|
+
yoloDesc: "Every shell command auto-runs, allowlist bypassed. Switch back with /mode review in the TUI.",
|
|
18972
|
+
project: "project",
|
|
18973
|
+
builtin: "builtin",
|
|
18974
|
+
addPrefix: "add a prefix",
|
|
18975
|
+
addPlaceholder: 'e.g. "npm run build" or "deploy.sh"',
|
|
18976
|
+
clearAll: "Clear all",
|
|
18977
|
+
alreadyIn: "{prefix} already in list",
|
|
18978
|
+
added: "added: {prefix}",
|
|
18979
|
+
removed: "removed: {prefix}",
|
|
18980
|
+
cleared: "cleared {count} entr{y}",
|
|
18981
|
+
removeConfirm: `Remove "{prefix}" from this project's allowlist?`,
|
|
18982
|
+
clearConfirm: "Wipe every project allowlist entry? Builtin entries are unaffected.",
|
|
18983
|
+
projectAllowlist: "Project allowlist \xB7 {count}",
|
|
18984
|
+
nothingStored: "Nothing stored yet for this project.",
|
|
18985
|
+
colNum: "#",
|
|
18986
|
+
colPrefix: "prefix",
|
|
18987
|
+
builtinTitle: "Builtin \xB7 {count} \xB7 read-only",
|
|
18988
|
+
standaloneWarning: "Mutations require /dashboard from inside an active reasonix code session \u2014 standalone reasonix dashboard can't tell which project's allowlist to edit."
|
|
18989
|
+
},
|
|
18990
|
+
mcp: {
|
|
18991
|
+
loading: "loading MCP\u2026",
|
|
18992
|
+
servers: "MCP servers \xB7 {count} bridged",
|
|
18993
|
+
all: "all",
|
|
18994
|
+
live: "live",
|
|
18995
|
+
unbridged: "unbridged",
|
|
18996
|
+
specPlaceholder: "spec \u2014 e.g. fs=npx -y @modelcontextprotocol/...",
|
|
18997
|
+
saved: "saved",
|
|
18998
|
+
savedRestart: "saved \u2014 restart reasonix code to bridge this server",
|
|
18999
|
+
removed: "removed \u2014 restart to drop the live bridge",
|
|
19000
|
+
removeConfirm: "Remove MCP spec from config?\n\n{spec}",
|
|
19001
|
+
noServers: "No MCP servers in this session.",
|
|
19002
|
+
tools: "tools",
|
|
19003
|
+
inConfig: "in config \xB7 not loaded",
|
|
19004
|
+
unbridgedTitle: "unbridged \xB7 in config",
|
|
19005
|
+
removeBtn: "Remove",
|
|
19006
|
+
spec: "spec",
|
|
19007
|
+
whyUnbridged: "Why unbridged?",
|
|
19008
|
+
whyUnbridgedDesc: "This spec lives in your config.json but isn't bridged into the live session. MCP servers attach when reasonix code starts; the dashboard alone can't spawn the child process.",
|
|
19009
|
+
whyUnbridgedHint: "To activate: restart reasonix code, then refresh this dashboard.",
|
|
19010
|
+
pickHint: "Pick an MCP server on the left to inspect tools / resources / prompts.",
|
|
19011
|
+
toolsTitle: "Tools \xB7 {count}",
|
|
19012
|
+
resourcesTitle: "Resources \xB7 {count}",
|
|
19013
|
+
promptsTitle: "Prompts \xB7 {count}",
|
|
19014
|
+
colName: "name",
|
|
19015
|
+
colDesc: "description",
|
|
19016
|
+
colUri: "uri"
|
|
19017
|
+
},
|
|
19018
|
+
memory: {
|
|
19019
|
+
loading: "loading memory\u2026",
|
|
19020
|
+
files: "memory \xB7 {count} files",
|
|
19021
|
+
exists: "exists",
|
|
19022
|
+
create: "create",
|
|
19023
|
+
noFiles: "No memory files yet.",
|
|
19024
|
+
pickHint: "Pick a memory file on the left.",
|
|
19025
|
+
pickDesc: "Project REASONIX.md is committable; global notes live in ~/.reasonix/memory/.",
|
|
19026
|
+
chars: "{count} chars",
|
|
19027
|
+
saved: "saved {scope}",
|
|
19028
|
+
reloadHint: "re-applied on next /new or session restart"
|
|
19029
|
+
},
|
|
19030
|
+
hooks: {
|
|
19031
|
+
loading: "loading hooks\u2026",
|
|
19032
|
+
resolved: "resolved",
|
|
19033
|
+
eventMatrix: "Event matrix",
|
|
19034
|
+
matrixSub: "{scripts} script{s} \xD7 {events} event{s}",
|
|
19035
|
+
noHooks: "No hooks configured. Edit the JSON below to add some.",
|
|
19036
|
+
colScript: "script",
|
|
19037
|
+
noProject: "No active project \u2014 open /dashboard from reasonix code to edit project hooks.",
|
|
19038
|
+
saveReload: "Save + Reload",
|
|
19039
|
+
discard: "Discard changes",
|
|
19040
|
+
savedReloaded: "saved + reloaded {scope}",
|
|
19041
|
+
recentRuns: "Recent runs",
|
|
19042
|
+
noRuns: "No hook runs in the recent session log.",
|
|
19043
|
+
colWhen: "when",
|
|
19044
|
+
colPhase: "phase",
|
|
19045
|
+
colHook: "hook",
|
|
19046
|
+
colOutcome: "outcome"
|
|
19047
|
+
},
|
|
19048
|
+
skills: {
|
|
19049
|
+
loading: "loading skills\u2026",
|
|
19050
|
+
filterPlaceholder: "filter skills",
|
|
19051
|
+
project: "project",
|
|
19052
|
+
global: "global",
|
|
19053
|
+
builtin: "builtin",
|
|
19054
|
+
newSkill: "new skill",
|
|
19055
|
+
noDescription: "(no description)",
|
|
19056
|
+
runs7d: "runs \xB7 7d",
|
|
19057
|
+
pickHint: "Pick a skill on the left, or create a new one above.",
|
|
19058
|
+
readOnlyBuiltin: "read-only \xB7 builtin",
|
|
19059
|
+
builtinDesc: "Built-in skills ship with Reasonix; the model picks them up automatically. To customize, create a project- or global-scoped skill with the same name.",
|
|
19060
|
+
saved: "saved {scope}/{name}",
|
|
19061
|
+
deleteConfirm: "Delete skill {scope}/{name}?",
|
|
19062
|
+
reloadHint: "re-loaded on next /new or session restart"
|
|
19063
|
+
},
|
|
19064
|
+
system: {
|
|
19065
|
+
loading: "loading health\u2026",
|
|
19066
|
+
failed: "health failed: {error}",
|
|
19067
|
+
healthChecks: "Health checks",
|
|
19068
|
+
version: "version",
|
|
19069
|
+
checking: "checking",
|
|
19070
|
+
latest: "\u25CF latest",
|
|
19071
|
+
outOfDate: "\u25CF out of date",
|
|
19072
|
+
versionPending: "version check pending",
|
|
19073
|
+
upToDate: "up to date",
|
|
19074
|
+
latestVer: "latest: {version}",
|
|
19075
|
+
sessions: "sessions",
|
|
19076
|
+
ok: "\u25CF ok",
|
|
19077
|
+
memory: "memory",
|
|
19078
|
+
semanticIndex: "semantic index",
|
|
19079
|
+
built: "\u25CF built",
|
|
19080
|
+
none: "\u2014 none",
|
|
19081
|
+
runIndex: "run reasonix index to build",
|
|
19082
|
+
usageLog: "usage log",
|
|
19083
|
+
backgroundJobs: "background jobs",
|
|
19084
|
+
noSession: "\u2014 no session",
|
|
19085
|
+
running: "{count} running",
|
|
19086
|
+
attachHint: "attach a session to see jobs",
|
|
19087
|
+
shellSpawn: "shell + spawn",
|
|
19088
|
+
paths: "paths",
|
|
19089
|
+
home: "home",
|
|
19090
|
+
sessionsPath: "sessions",
|
|
19091
|
+
memoryPath: "memory",
|
|
19092
|
+
semanticPath: "semantic",
|
|
19093
|
+
usagePath: "usage"
|
|
19094
|
+
},
|
|
19095
|
+
plans: {
|
|
19096
|
+
loading: "loading plans\u2026",
|
|
19097
|
+
failed: "plans failed: {error}",
|
|
19098
|
+
noPlans: "No archived plans yet \u2014 run a turn that calls submit_plan and mark_step_complete.",
|
|
19099
|
+
filterPlaceholder: "filter plans",
|
|
19100
|
+
active: "active",
|
|
19101
|
+
done: "done",
|
|
19102
|
+
steps: "steps",
|
|
19103
|
+
pickHint: "Pick a plan on the left.",
|
|
19104
|
+
noTitle: "(no title)",
|
|
19105
|
+
stepTimeline: "Step timeline \xB7 {done} / {total}",
|
|
19106
|
+
step: "step {n}"
|
|
19107
|
+
},
|
|
19108
|
+
semantic: {
|
|
19109
|
+
codeRequired: "Semantic \u2014 code-mode required",
|
|
19110
|
+
indexBuilt: "index built",
|
|
19111
|
+
noIndex: "no index yet",
|
|
19112
|
+
ready: "ready",
|
|
19113
|
+
setupNeeded: "setup needed",
|
|
19114
|
+
installOllama: "Install Ollama",
|
|
19115
|
+
installOllamaDesc: "Reasonix doesn't run package managers for you. Install Ollama first, then come back:",
|
|
19116
|
+
macWindows: "macOS / Windows:",
|
|
19117
|
+
download: "download from ollama.com/download",
|
|
19118
|
+
linux: "Linux:",
|
|
19119
|
+
refreshHint: "Refresh after install \u2014 this panel will offer to start the daemon and pull {model}.",
|
|
19120
|
+
daemon: "Daemon",
|
|
19121
|
+
daemonDesc: "ollama is on your PATH but the HTTP daemon isn't reachable.",
|
|
19122
|
+
startDaemon: "Start daemon",
|
|
19123
|
+
runsOllama: "runs ollama serve detached",
|
|
19124
|
+
model: "Model",
|
|
19125
|
+
modelMissing: "{model} isn't installed yet.",
|
|
19126
|
+
modelSize: "~270 MB on first pull.",
|
|
19127
|
+
pulling: "pulling\u2026",
|
|
19128
|
+
pullModel: "Pull {model}",
|
|
19129
|
+
indexStatus: "index status",
|
|
19130
|
+
builtStatus: "\u25CF built",
|
|
19131
|
+
chunks: "chunks",
|
|
19132
|
+
files: "files",
|
|
19133
|
+
dim: "dim",
|
|
19134
|
+
size: "size",
|
|
19135
|
+
lastBuild: "last build",
|
|
19136
|
+
runIndexHint: "Run an index to enable semantic_search.",
|
|
19137
|
+
reIndex: "Re-index",
|
|
19138
|
+
build: "Build",
|
|
19139
|
+
rebuild: "Rebuild",
|
|
19140
|
+
stop: "Stop",
|
|
19141
|
+
ollama: "ollama",
|
|
19142
|
+
binary: "binary",
|
|
19143
|
+
found: "found",
|
|
19144
|
+
missing: "missing",
|
|
19145
|
+
daemonStatus: "daemon",
|
|
19146
|
+
up: "up",
|
|
19147
|
+
down: "down",
|
|
19148
|
+
pulled: "pulled",
|
|
19149
|
+
indexConfig: "index config",
|
|
19150
|
+
reset: "reset",
|
|
19151
|
+
excludeDirs: "exclude dirs",
|
|
19152
|
+
excludeFiles: "exclude files",
|
|
19153
|
+
excludeExts: "exclude exts",
|
|
19154
|
+
excludePatterns: "exclude patterns",
|
|
19155
|
+
glob: "glob",
|
|
19156
|
+
respectGitignore: "respect .gitignore",
|
|
19157
|
+
maxFileBytes: "max file bytes",
|
|
19158
|
+
skipLarger: "skip files larger than ~{size} MiB",
|
|
19159
|
+
preview: "Preview",
|
|
19160
|
+
searchPlaceholder: "describe what to find \u2014 'where do we handle abort signals'",
|
|
19161
|
+
searching: "searching\u2026",
|
|
19162
|
+
results: "{count} result{s} \xB7 {ms}ms \xB7 {model}",
|
|
19163
|
+
noMatches: "No matches above the score threshold.",
|
|
19164
|
+
previewSummary: "Preview \u2014 would index {included} file(s), skip {skipped}",
|
|
19165
|
+
nothingSkipped: "nothing skipped \u2014 all walked files would be indexed.",
|
|
19166
|
+
firstIncluded: "first {count} included file(s)",
|
|
19167
|
+
job: "Job",
|
|
19168
|
+
phaseScan: "scanning files",
|
|
19169
|
+
phaseEmbed: "embedding chunks",
|
|
19170
|
+
phaseWrite: "writing index",
|
|
19171
|
+
phaseDone: "done",
|
|
19172
|
+
phaseError: "error",
|
|
19173
|
+
stopping: "stopping",
|
|
19174
|
+
scanned: "scanned {count}",
|
|
19175
|
+
changed: "changed {count}",
|
|
19176
|
+
skipped: "skipped {count}",
|
|
19177
|
+
chunksProgress: "{done} / {total} ({pct}%)",
|
|
19178
|
+
result: "result",
|
|
19179
|
+
added: "added {count}",
|
|
19180
|
+
removed: "removed {count}",
|
|
19181
|
+
failed: "failed {count}",
|
|
19182
|
+
skippedFiles: "{total} files ({details})",
|
|
19183
|
+
rebuildStarted: "rebuild started",
|
|
19184
|
+
incrementalStarted: "incremental index started",
|
|
19185
|
+
stopRequested: "stopping requested \u2014 current chunk batch will finish first",
|
|
19186
|
+
startingDaemon: "starting ollama daemon (15s timeout)\u2026",
|
|
19187
|
+
daemonUp: "daemon is up",
|
|
19188
|
+
daemonTimeout: "daemon didn't come up in time \u2014 check ollama serve manually",
|
|
19189
|
+
pullingModel: "pulling {model} \u2014 this may take a few minutes on first install",
|
|
19190
|
+
savedConfig: "saved \xB7 {count} fields updated \xB7 re-run index to apply",
|
|
19191
|
+
runningPreview: "running dry walk against project root\u2026",
|
|
19192
|
+
exclude: "exclude"
|
|
19193
|
+
},
|
|
19194
|
+
modal: {
|
|
19195
|
+
shellTitle: "shell command",
|
|
19196
|
+
shellBgTitle: "background process",
|
|
19197
|
+
shellSubtitle: "model wants to run a shell command",
|
|
19198
|
+
shellBgSubtitle: "long-running \u2014 keeps running after approval",
|
|
19199
|
+
runOnce: "Run once",
|
|
19200
|
+
alwaysAllow: 'Always allow "{prefix}"',
|
|
19201
|
+
deny: "Deny",
|
|
19202
|
+
choiceTitle: "model wants you to pick",
|
|
19203
|
+
typeOwn: "Type my own answer",
|
|
19204
|
+
typeOwnSummary: "None of the above fits \u2014 write a free-form reply.",
|
|
19205
|
+
typePlaceholder: "Type a free-form answer\u2026",
|
|
19206
|
+
send: "Send",
|
|
19207
|
+
cancel: "Cancel",
|
|
19208
|
+
cancelSummary: "Drop the question. Model will ask what you actually want.",
|
|
19209
|
+
planTitle: "plan submitted",
|
|
19210
|
+
planSubtitle: "model proposed a plan; review then pick",
|
|
19211
|
+
approveInstructions: "Optional last instructions / answers to open questions (Enter to send blank)",
|
|
19212
|
+
refinePlaceholder: "What needs to change? Be specific.",
|
|
19213
|
+
approve: "Approve",
|
|
19214
|
+
refine: "Refine",
|
|
19215
|
+
sendRefinement: "Send refinement",
|
|
19216
|
+
editTitle: "edit pending review",
|
|
19217
|
+
editSubtitle: "{path} \xB7 {remaining} of {total} blocks remaining",
|
|
19218
|
+
before: "before",
|
|
19219
|
+
after: "after",
|
|
19220
|
+
workspaceTitle: "model wants to switch workspace",
|
|
19221
|
+
workspaceSubtitle: "every subsequent file / shell / memory tool resolves against the new root",
|
|
19222
|
+
switchBtn: "Switch (Enter)",
|
|
19223
|
+
denyBtn: "Deny (Esc)",
|
|
19224
|
+
stepComplete: "step complete{counter}",
|
|
19225
|
+
continueBtn: "Continue",
|
|
19226
|
+
reviseBtn: "Revise\u2026",
|
|
19227
|
+
stopBtn: "Stop",
|
|
19228
|
+
revisionTitle: "model proposed a plan revision",
|
|
19229
|
+
sendRevision: "Send revision",
|
|
19230
|
+
accept: "Accept",
|
|
19231
|
+
reject: "Reject",
|
|
19232
|
+
arguments: "arguments",
|
|
19233
|
+
revisePlaceholder: "What needs to change before the next step? Leave blank to just continue."
|
|
19234
|
+
}
|
|
19235
|
+
};
|
|
19236
|
+
|
|
19237
|
+
// dashboard/src/i18n/zh-CN.ts
|
|
19238
|
+
var zhCN = {
|
|
19239
|
+
app: {
|
|
19240
|
+
sectionWorkspace: "\u5DE5\u4F5C\u533A",
|
|
19241
|
+
sectionObserve: "\u76D1\u63A7",
|
|
19242
|
+
sectionConfigure: "\u914D\u7F6E",
|
|
19243
|
+
tabChat: "\u5BF9\u8BDD",
|
|
19244
|
+
tabPlans: "\u8BA1\u5212",
|
|
19245
|
+
tabSessions: "\u4F1A\u8BDD",
|
|
19246
|
+
tabOverview: "\u6982\u89C8",
|
|
19247
|
+
tabUsage: "\u7528\u91CF",
|
|
19248
|
+
tabSystem: "\u7CFB\u7EDF",
|
|
19249
|
+
tabSemantic: "\u8BED\u4E49",
|
|
19250
|
+
tabTools: "\u5DE5\u5177",
|
|
19251
|
+
tabPermissions: "\u6743\u9650",
|
|
19252
|
+
tabMcp: "MCP",
|
|
19253
|
+
tabSkills: "\u6280\u80FD",
|
|
19254
|
+
tabMemory: "\u8BB0\u5FC6",
|
|
19255
|
+
tabHooks: "\u94A9\u5B50",
|
|
19256
|
+
tabSettings: "\u8BBE\u7F6E",
|
|
19257
|
+
footer: "\u4EC5 127.0.0.1 \xB7 Token \u4FDD\u62A4"
|
|
19258
|
+
},
|
|
19259
|
+
common: {
|
|
19260
|
+
loading: "\u52A0\u8F7D\u4E2D\u2026",
|
|
19261
|
+
loadingFailed: "{name}\u5931\u8D25\uFF1A{error}",
|
|
19262
|
+
back: "\u2190 \u8FD4\u56DE",
|
|
19263
|
+
save: "\u4FDD\u5B58",
|
|
19264
|
+
remove: "\u79FB\u9664",
|
|
19265
|
+
cancel: "\u53D6\u6D88",
|
|
19266
|
+
delete: "\u5220\u9664",
|
|
19267
|
+
add: "\u6DFB\u52A0",
|
|
19268
|
+
confirm: "\u786E\u8BA4",
|
|
19269
|
+
noData: "\u6682\u65E0{name}\u3002",
|
|
19270
|
+
all: "\u5168\u90E8",
|
|
19271
|
+
yes: "\u662F",
|
|
19272
|
+
no: "\u5426",
|
|
19273
|
+
on: "\u5F00\u542F",
|
|
19274
|
+
off: "\u5173\u95ED",
|
|
19275
|
+
enabled: "\u5DF2\u542F\u7528",
|
|
19276
|
+
disabled: "\u5DF2\u7981\u7528"
|
|
19277
|
+
},
|
|
19278
|
+
settings: {
|
|
19279
|
+
title: "\u8BBE\u7F6E",
|
|
19280
|
+
loading: "\u52A0\u8F7D\u8BBE\u7F6E\u2026",
|
|
19281
|
+
saved: "\u5DF2\u4FDD\u5B58\uFF1A{fields}",
|
|
19282
|
+
sectionApi: "DeepSeek API",
|
|
19283
|
+
apiKey: "API \u5BC6\u94A5",
|
|
19284
|
+
notSet: "\uFF08\u672A\u8BBE\u7F6E\uFF09",
|
|
19285
|
+
replace: "\u66FF\u6362",
|
|
19286
|
+
pasteKey: "\u7C98\u8D34\u65B0\u7684 sk-\u2026 \u4EE4\u724C",
|
|
19287
|
+
saveKey: "\u4FDD\u5B58\u5BC6\u94A5",
|
|
19288
|
+
baseUrl: "\u57FA\u7840 URL",
|
|
19289
|
+
baseUrlPlaceholder: "https://api.deepseek.com\uFF08\u9ED8\u8BA4\uFF09",
|
|
19290
|
+
sectionDefaults: "\u9ED8\u8BA4\u8BBE\u7F6E",
|
|
19291
|
+
preset: "\u9884\u8BBE",
|
|
19292
|
+
presetAuto: "auto \u2014 flash \u57FA\u7EBF\uFF0C\u56F0\u96BE\u65F6\u81EA\u52A8\u5347\u7EA7\u4E3A pro",
|
|
19293
|
+
presetFlash: "flash \u2014 \u59CB\u7EC8\u4F7F\u7528 flash\uFF0C\u4E0D\u81EA\u52A8\u5347\u7EA7",
|
|
19294
|
+
presetPro: "pro \u2014 \u59CB\u7EC8\u4F7F\u7528 pro",
|
|
19295
|
+
appliesNextTurn: "\u4E0B\u4E00\u8F6E\u751F\u6548",
|
|
19296
|
+
effort: "\u63A8\u7406\u5F3A\u5EA6",
|
|
19297
|
+
effortMax: "max\uFF08\u9ED8\u8BA4 \u2014 \u6700\u4F73\u8D28\u91CF\uFF09",
|
|
19298
|
+
effortHigh: "high\uFF08\u66F4\u4FBF\u5B9C / \u66F4\u5FEB\uFF09",
|
|
19299
|
+
webSearch: "\u7F51\u9875\u641C\u7D22",
|
|
19300
|
+
webSearchNote: "web_fetch + web_search \u5DE5\u5177",
|
|
19301
|
+
sectionRuntime: "\u8FD0\u884C\u65F6",
|
|
19302
|
+
activeModel: "\u5F53\u524D\u6A21\u578B",
|
|
19303
|
+
editMode: "\u7F16\u8F91\u6A21\u5F0F",
|
|
19304
|
+
editModeNote: "\u5728\u5BF9\u8BDD\u6807\u7B7E\u9875\u5934\u90E8\u5207\u6362",
|
|
19305
|
+
sectionLanguage: "\u8BED\u8A00",
|
|
19306
|
+
language: "\u8BED\u8A00",
|
|
19307
|
+
langEn: "English",
|
|
19308
|
+
langZhCn: "\u7B80\u4F53\u4E2D\u6587"
|
|
19309
|
+
},
|
|
19310
|
+
chat: {
|
|
19311
|
+
modeMirror: "TUI \u955C\u50CF",
|
|
19312
|
+
modeView: "\u4F1A\u8BDD\u89C6\u56FE",
|
|
19313
|
+
placeholder: "\u8F93\u5165\u63D0\u793A\u8BCD \u2014 Enter \u53D1\u9001\uFF0CShift+Enter \u6362\u884C \xB7 / @ \u6253\u5F00\u9009\u62E9\u5668",
|
|
19314
|
+
placeholderBusy: "\u8BF7\u7B49\u5F85\u5F53\u524D\u8F6E\u6B21\u5B8C\u6210\u2026",
|
|
19315
|
+
send: "\u53D1\u9001",
|
|
19316
|
+
new: "\u65B0\u5EFA",
|
|
19317
|
+
clear: "\u6E05\u9664",
|
|
19318
|
+
newTitle: "/new \u2014 \u6E05\u9664\u5BF9\u8BDD\u4E0A\u4E0B\u6587\uFF08\u5FAA\u73AF\u65E5\u5FD7 + \u6EDA\u52A8\u56DE\u653E\uFF09",
|
|
19319
|
+
clearTitle: "/clear \u2014 \u4EC5\u6E05\u9664\u53EF\u89C1\u7684\u6EDA\u52A8\u56DE\u653E\uFF08\u4E0A\u4E0B\u6587\u4FDD\u7559\uFF09",
|
|
19320
|
+
noConversation: "\u6682\u65E0\u5BF9\u8BDD\u3002\u5728\u4E0B\u65B9\u53D1\u9001\u63D0\u793A\u8BCD\u5F00\u59CB\u3002",
|
|
19321
|
+
newConfirmBusy: "\u6709\u8F6E\u6B21\u6B63\u5728\u6267\u884C\u3002\u4E2D\u6B62\u5E76\u5F00\u59CB\u65B0\u5BF9\u8BDD\uFF1F",
|
|
19322
|
+
newConfirm: "\u6E05\u9664\u5F53\u524D\u5BF9\u8BDD\u5E76\u91CD\u65B0\u5F00\u59CB\uFF1F",
|
|
19323
|
+
newToast: "\u65B0\u5BF9\u8BDD",
|
|
19324
|
+
clearToast: "\u6EDA\u52A8\u56DE\u653E\u5DF2\u6E05\u9664",
|
|
19325
|
+
newFailed: "/new \u5931\u8D25\uFF1A{error}",
|
|
19326
|
+
clearFailed: "/clear \u5931\u8D25\uFF1A{error}",
|
|
19327
|
+
eventStreamError: "\u4E8B\u4EF6\u6D41\u4E2D\u65AD \u2014 \u6B63\u5728\u91CD\u8FDE\u2026",
|
|
19328
|
+
semanticBanner: "\u6B64\u9879\u76EE\u672A\u542F\u7528\u8BED\u4E49\u641C\u7D22\u3002",
|
|
19329
|
+
semanticBannerDesc: "\u6784\u5EFA\u4E00\u6B21\u7D22\u5F15\uFF0C\u6A21\u578B\u5373\u53EF\u6309\u542B\u4E49\u67E5\u627E\u4EE3\u7801\uFF08\u201C\u54EA\u91CC\u5904\u7406\u8BA4\u8BC1\u5931\u8D25\uFF1F\u201D\uFF09\uFF0C\u800C\u4E0D\u4EC5\u4F9D\u8D56\u7CBE\u786E\u5B57\u7B26\u4E32\u7684 grep\u3002",
|
|
19330
|
+
semanticBannerBtn: "\u6784\u5EFA \u2192",
|
|
19331
|
+
semanticBannerDismiss: "\u5173\u95ED\uFF08\u4E0D\u518D\u663E\u793A\uFF09",
|
|
19332
|
+
slashCommands: "\u659C\u6760\u547D\u4EE4",
|
|
19333
|
+
projectFiles: "\u9879\u76EE\u6587\u4EF6",
|
|
19334
|
+
effortTitle: "reasoning_effort \u2014 \u4E0B\u4E00\u8F6E\u751F\u6548",
|
|
19335
|
+
effortMaxTitle: "max\uFF08\u9ED8\u8BA4 \u2014 \u6700\u4F73\u8D28\u91CF\uFF09",
|
|
19336
|
+
effortHighTitle: "high\uFF08\u66F4\u4FBF\u5B9C / \u66F4\u5FEB\uFF09",
|
|
19337
|
+
presetTitle: "\u9884\u8BBE \u2014 \u6A21\u578B\u627F\u8BFA",
|
|
19338
|
+
presetAutoTitle: "auto \u2014 flash \u57FA\u7EBF\uFF1B\u56F0\u96BE\u8F6E\u6B21\u81EA\u52A8\u5347\u7EA7\u4E3A pro\uFF08NEEDS_PRO / \u5931\u8D25\u9608\u503C\uFF09",
|
|
19339
|
+
presetFlashTitle: "flash \u2014 \u59CB\u7EC8 flash\uFF1B\u4E0D\u81EA\u52A8\u5347\u7EA7\u3002/pro \u4ECD\u53EF\u7528\u4E8E\u4E00\u6B21\u6027\u624B\u52A8\u63D0\u5347",
|
|
19340
|
+
presetProTitle: "pro \u2014 \u59CB\u7EC8 pro\uFF1B\u7EA6 3 \u500D flash \u6210\u672C\uFF085/31 \u6298\u6263\uFF09\u3002\u9501\u5B9A\u56F0\u96BE\u7684\u67B6\u6784\u5DE5\u4F5C\u3002",
|
|
19341
|
+
editGateTitle: "\u7F16\u8F91\u95E8\u63A7 \u2014 Shift+Tab \u5728 TUI \u4E2D\u5FAA\u73AF",
|
|
19342
|
+
editReviewTitle: "review \u2014 \u7F16\u8F91\u548C\u975E\u5141\u8BB8\u5217\u8868\u7684 shell \u547D\u4EE4\u90FD\u4F1A\u5148\u8BE2\u95EE",
|
|
19343
|
+
editAutoTitle: "auto \u2014 \u7F16\u8F91\u81EA\u52A8\u5E94\u7528\uFF0Cshell \u4ECD\u4F1A\u8BE2\u95EE",
|
|
19344
|
+
editYoloTitle: "yolo \u2014 \u7F16\u8F91\u548C shell \u90FD\u81EA\u52A8\u8FD0\u884C\uFF0C\u7ED5\u8FC7\u5141\u8BB8\u5217\u8868",
|
|
19345
|
+
railSession: "\u4F1A\u8BDD",
|
|
19346
|
+
railTurns: "\u8F6E\u6B21",
|
|
19347
|
+
railPromptTok: "\u63D0\u793A tokens",
|
|
19348
|
+
railCost: "\u8D39\u7528",
|
|
19349
|
+
railCacheHit: "\u7F13\u5B58\u547D\u4E2D",
|
|
19350
|
+
railToolBudget: "\u5DE5\u5177\u9884\u7B97",
|
|
19351
|
+
railSpend: "\u5DF2\u7528",
|
|
19352
|
+
railActivePlan: "\u6D3B\u8DC3\u8BA1\u5212",
|
|
19353
|
+
railProgress: "\u8FDB\u5EA6",
|
|
19354
|
+
statusModel: "\u6A21\u578B",
|
|
19355
|
+
statusCtx: "\u4E0A\u4E0B\u6587",
|
|
19356
|
+
statusCache: "\u7F13\u5B58",
|
|
19357
|
+
statusTurn: "\u8F6E\u6B21",
|
|
19358
|
+
statusSession: "\u4F1A\u8BDD",
|
|
19359
|
+
statusBalance: "\u4F59\u989D",
|
|
19360
|
+
statusTurns: "{count} \u8F6E",
|
|
19361
|
+
waitingStats: "\xB7 \xB7 \xB7 \u7B49\u5F85\u5B9E\u65F6\u7EDF\u8BA1",
|
|
19362
|
+
inflightPhase: "{phase}",
|
|
19363
|
+
inflightRunning: "\u8FD0\u884C\u4E2D",
|
|
19364
|
+
inflightThinking: "\u601D\u8003\u4E2D",
|
|
19365
|
+
inflightStreaming: "\u8F93\u51FA\u4E2D",
|
|
19366
|
+
inflightWaiting: "\u7B49\u5F85\u4E2D",
|
|
19367
|
+
inflightReasoning: "\u63A8\u7406 {count} \u5B57\u7B26",
|
|
19368
|
+
inflightOut: "\u8F93\u51FA {count} \u5B57\u7B26",
|
|
19369
|
+
abortBtn: "\u4E2D\u6B62 (Esc)",
|
|
19370
|
+
confirmBtn: "\u5E94\u7528 (y)",
|
|
19371
|
+
rejectBtn: "\u62D2\u7EDD (n)",
|
|
19372
|
+
applyRestBtn: "\u5E94\u7528\u5269\u4F59 (a)",
|
|
19373
|
+
flipAutoBtn: "\u5207\u6362\u4E3A AUTO (A)"
|
|
19374
|
+
},
|
|
19375
|
+
overview: {
|
|
19376
|
+
loading: "\u52A0\u8F7D\u6982\u89C8\u2026",
|
|
19377
|
+
failed: "\u6982\u89C8\u5931\u8D25\uFF1A{error}",
|
|
19378
|
+
standaloneTitle: "\u72EC\u7ACB\u6A21\u5F0F",
|
|
19379
|
+
standaloneDesc: "\u53EA\u8BFB\u78C1\u76D8\u89C6\u56FE\u3002\u5728 reasonix code \u5185\u542F\u52A8 /dashboard \u4EE5\u83B7\u53D6\u5B9E\u65F6\u4F1A\u8BDD\u72B6\u6001\u3001MCP \u548C\u5DE5\u5177\u3002",
|
|
19380
|
+
cockpit: "\u9A7E\u9A76\u8231",
|
|
19381
|
+
balance: "\u4F59\u989D",
|
|
19382
|
+
tokens7d: "tokens \xB7 7 \u5929",
|
|
19383
|
+
cacheHit: "\u7F13\u5B58\u547D\u4E2D",
|
|
19384
|
+
toolCalls24h: "\u5DE5\u5177\u8C03\u7528 \xB7 24 \u5C0F\u65F6",
|
|
19385
|
+
currentSession: "\u5F53\u524D\u4F1A\u8BDD",
|
|
19386
|
+
noSession: "\u65E0\u6D3B\u8DC3\u4F1A\u8BDD \u2014 \u5728 reasonix code \u5185\u6267\u884C /dashboard \u8FDB\u884C\u8FDE\u63A5\u3002",
|
|
19387
|
+
promptTok: "\u63D0\u793A tokens",
|
|
19388
|
+
completionTok: "\u8865\u5168 tokens",
|
|
19389
|
+
cost: "\u8D39\u7528",
|
|
19390
|
+
costTrend: "\u8D39\u7528 \xB7 14 \u5929",
|
|
19391
|
+
noUsageYet: "\u6682\u65E0\u7528\u91CF",
|
|
19392
|
+
dayAvg: "/\u5929 \u5747\u503C",
|
|
19393
|
+
recentPlans: "\u8FD1\u671F\u8BA1\u5212",
|
|
19394
|
+
noPlans: "\u6682\u65E0\u8BA1\u5212 \u2014 \u4F7F\u7528 submit_plan \u63D0\u4EA4\u4E00\u4E2A\u3002",
|
|
19395
|
+
toolActivity: "\u5DE5\u5177\u6D3B\u52A8",
|
|
19396
|
+
noToolCalls: "\u6682\u65E0\u5DE5\u5177\u8C03\u7528\u3002",
|
|
19397
|
+
toolsLoaded: "\u5DF2\u52A0\u8F7D\u5DE5\u5177",
|
|
19398
|
+
mcpServers: "MCP \u670D\u52A1\u5668",
|
|
19399
|
+
editMode: "\u7F16\u8F91\u6A21\u5F0F",
|
|
19400
|
+
version: "Reasonix",
|
|
19401
|
+
workingDir: "\u5DE5\u4F5C\u76EE\u5F55",
|
|
19402
|
+
projectRoot: "\u9879\u76EE\u6839\u76EE\u5F55",
|
|
19403
|
+
noPriorData: "\u65E0\u5386\u53F2\u6570\u636E",
|
|
19404
|
+
stable: "\u2014 \u7A33\u5B9A",
|
|
19405
|
+
vsPrior: "{arrow} {pct}% \u8F83\u4E0A\u671F",
|
|
19406
|
+
active: "\u6D3B\u8DC3",
|
|
19407
|
+
allUp: "\u5168\u90E8\u5728\u7EBF",
|
|
19408
|
+
yoloWarning: "\u6240\u6709\u63D0\u793A\u88AB\u7ED5\u8FC7",
|
|
19409
|
+
checking: "\u68C0\u67E5\u4E2D",
|
|
19410
|
+
latest: "\u6700\u65B0"
|
|
19411
|
+
},
|
|
19412
|
+
usage: {
|
|
19413
|
+
loading: "\u52A0\u8F7D\u7528\u91CF\u2026",
|
|
19414
|
+
failed: "\u7528\u91CF\u5931\u8D25\uFF1A{error}",
|
|
19415
|
+
records: "{count} \u6761\u8BB0\u5F55",
|
|
19416
|
+
dailyUsage: "\u6BCF\u65E5\u7528\u91CF",
|
|
19417
|
+
dailyMeta: "\u8D39\u7528 \xB7 \u7F13\u5B58\u8282\u7701 \xB7 \u8F6E\u6B21",
|
|
19418
|
+
noData: "\u6682\u65E0\u7528\u91CF\u6570\u636E \u2014 \u5728 reasonix chat / code / run \u4E2D\u6267\u884C\u4E00\u8F6E\uFF0C\u7136\u540E\u5237\u65B0\u3002",
|
|
19419
|
+
windows: "\u6EDA\u52A8\u7A97\u53E3",
|
|
19420
|
+
colTurns: "\u8F6E\u6B21",
|
|
19421
|
+
colCacheHit: "\u7F13\u5B58\u547D\u4E2D",
|
|
19422
|
+
colCost: "\u8D39\u7528 (USD)",
|
|
19423
|
+
colCacheSaved: "\u7F13\u5B58\u8282\u7701",
|
|
19424
|
+
colVsClaude: "\u5BF9\u6BD4 Claude",
|
|
19425
|
+
colSaved: "\u8282\u7701",
|
|
19426
|
+
mostUsed: "\u6700\u5E38\u7528\u6A21\u578B",
|
|
19427
|
+
colModel: "\u6A21\u578B"
|
|
19428
|
+
},
|
|
19429
|
+
sessions: {
|
|
19430
|
+
loading: "\u52A0\u8F7D\u4F1A\u8BDD\u2026",
|
|
19431
|
+
failed: "\u4F1A\u8BDD\u5931\u8D25\uFF1A{error}",
|
|
19432
|
+
noSessions: "\u6682\u65E0\u5DF2\u4FDD\u5B58\u7684\u4F1A\u8BDD\u3002",
|
|
19433
|
+
filterPlaceholder: "\u7B5B\u9009\u4F1A\u8BDD",
|
|
19434
|
+
msgs: "\u6761\u6D88\u606F",
|
|
19435
|
+
pickHint: "\u9009\u62E9\u5DE6\u4FA7\u7684\u4F1A\u8BDD\u4EE5\u67E5\u770B\u5176\u8F6C\u5F55\u7A3F\u3002",
|
|
19436
|
+
resumeTitle: "\u5728 TUI \u4E2D\u6062\u590D",
|
|
19437
|
+
resumeDesc: "\u4F1A\u8BDD\u4E2D\u9014\u5207\u6362\u9700\u8981\u91CD\u542F\uFF0C\u4EE5\u4FBF\u6D88\u606F\u65E5\u5FD7\u53EF\u4EE5\u5E72\u51C0\u5730\u56DE\u9000\u3002\u8BF7\u9000\u51FA\u5F53\u524D\u4F1A\u8BDD\uFF0C\u7136\u540E\u8FD0\u884C\uFF1A",
|
|
19438
|
+
loadingTranscript: "\u52A0\u8F7D\u8F6C\u5F55\u7A3F\u2026",
|
|
19439
|
+
emptyTranscript: "\u7A7A\u7684\u8F6C\u5F55\u7A3F\u3002",
|
|
19440
|
+
messages: "{count} \u6761\u6D88\u606F"
|
|
19441
|
+
},
|
|
19442
|
+
tools: {
|
|
19443
|
+
loading: "\u52A0\u8F7D\u5DE5\u5177\u2026",
|
|
19444
|
+
failed: "\u5DE5\u5177\u5931\u8D25\uFF1A{error}",
|
|
19445
|
+
noTools: "\u672A\u6CE8\u518C\u4EFB\u4F55\u5DE5\u5177\u3002",
|
|
19446
|
+
planMode: "\u8BA1\u5212\u6A21\u5F0F \u2014 \u5199\u5165\u53D7\u9650",
|
|
19447
|
+
colTool: "\u5DE5\u5177",
|
|
19448
|
+
colFlags: "\u6807\u5FD7",
|
|
19449
|
+
colDesc: "\u63CF\u8FF0",
|
|
19450
|
+
readOnly: "\u53EA\u8BFB",
|
|
19451
|
+
write: "\u5199\u5165",
|
|
19452
|
+
flat: "\u6241\u5E73"
|
|
19453
|
+
},
|
|
19454
|
+
permissions: {
|
|
19455
|
+
loading: "\u52A0\u8F7D\u6743\u9650\u2026",
|
|
19456
|
+
failed: "\u6743\u9650\u5931\u8D25\uFF1A{error}",
|
|
19457
|
+
yoloTitle: "YOLO \u6A21\u5F0F",
|
|
19458
|
+
yoloDesc: "\u6240\u6709 shell \u547D\u4EE4\u81EA\u52A8\u8FD0\u884C\uFF0C\u5141\u8BB8\u5217\u8868\u88AB\u7ED5\u8FC7\u3002\u5728 TUI \u4E2D\u4F7F\u7528 /mode review \u5207\u6362\u56DE\u6765\u3002",
|
|
19459
|
+
project: "\u9879\u76EE",
|
|
19460
|
+
builtin: "\u5185\u7F6E",
|
|
19461
|
+
addPrefix: "\u6DFB\u52A0\u524D\u7F00",
|
|
19462
|
+
addPlaceholder: '\u4F8B\u5982 "npm run build" \u6216 "deploy.sh"',
|
|
19463
|
+
clearAll: "\u6E05\u9664\u5168\u90E8",
|
|
19464
|
+
alreadyIn: "{prefix} \u5DF2\u5728\u5217\u8868\u4E2D",
|
|
19465
|
+
added: "\u5DF2\u6DFB\u52A0\uFF1A{prefix}",
|
|
19466
|
+
removed: "\u5DF2\u79FB\u9664\uFF1A{prefix}",
|
|
19467
|
+
cleared: "\u5DF2\u6E05\u9664 {count} \u6761",
|
|
19468
|
+
removeConfirm: '\u4ECE\u6B64\u9879\u76EE\u7684\u5141\u8BB8\u5217\u8868\u4E2D\u79FB\u9664 "{prefix}"\uFF1F',
|
|
19469
|
+
clearConfirm: "\u6E05\u9664\u6240\u6709\u9879\u76EE\u5141\u8BB8\u5217\u8868\u6761\u76EE\uFF1F\u5185\u7F6E\u6761\u76EE\u4E0D\u53D7\u5F71\u54CD\u3002",
|
|
19470
|
+
projectAllowlist: "\u9879\u76EE\u5141\u8BB8\u5217\u8868 \xB7 {count}",
|
|
19471
|
+
nothingStored: "\u6B64\u9879\u76EE\u6682\u65E0\u5B58\u50A8\u7684\u6761\u76EE\u3002",
|
|
19472
|
+
colNum: "#",
|
|
19473
|
+
colPrefix: "\u524D\u7F00",
|
|
19474
|
+
builtinTitle: "\u5185\u7F6E \xB7 {count} \xB7 \u53EA\u8BFB",
|
|
19475
|
+
standaloneWarning: "\u4FEE\u6539\u64CD\u4F5C\u9700\u8981\u5728\u6D3B\u8DC3\u7684 reasonix code \u4F1A\u8BDD\u5185\u6267\u884C /dashboard \u2014 \u72EC\u7ACB\u6A21\u5F0F\u7684 reasonix dashboard \u65E0\u6CD5\u786E\u5B9A\u8981\u7F16\u8F91\u54EA\u4E2A\u9879\u76EE\u7684\u5141\u8BB8\u5217\u8868\u3002"
|
|
19476
|
+
},
|
|
19477
|
+
mcp: {
|
|
19478
|
+
loading: "\u52A0\u8F7D MCP\u2026",
|
|
19479
|
+
servers: "MCP \u670D\u52A1\u5668 \xB7 {count} \u4E2A\u5DF2\u6865\u63A5",
|
|
19480
|
+
all: "\u5168\u90E8",
|
|
19481
|
+
live: "\u5728\u7EBF",
|
|
19482
|
+
unbridged: "\u672A\u6865\u63A5",
|
|
19483
|
+
specPlaceholder: "\u89C4\u683C \u2014 \u4F8B\u5982 fs=npx -y @modelcontextprotocol/...",
|
|
19484
|
+
saved: "\u5DF2\u4FDD\u5B58",
|
|
19485
|
+
savedRestart: "\u5DF2\u4FDD\u5B58 \u2014 \u91CD\u542F reasonix code \u4EE5\u6865\u63A5\u6B64\u670D\u52A1\u5668",
|
|
19486
|
+
removed: "\u5DF2\u79FB\u9664 \u2014 \u91CD\u542F\u4EE5\u65AD\u5F00\u5B9E\u65F6\u6865\u63A5",
|
|
19487
|
+
removeConfirm: "\u4ECE\u914D\u7F6E\u4E2D\u79FB\u9664 MCP \u89C4\u683C\uFF1F\n\n{spec}",
|
|
19488
|
+
noServers: "\u6B64\u4F1A\u8BDD\u4E2D\u65E0 MCP \u670D\u52A1\u5668\u3002",
|
|
19489
|
+
tools: "\u4E2A\u5DE5\u5177",
|
|
19490
|
+
inConfig: "\u5728\u914D\u7F6E\u4E2D \xB7 \u672A\u52A0\u8F7D",
|
|
19491
|
+
unbridgedTitle: "\u672A\u6865\u63A5 \xB7 \u5728\u914D\u7F6E\u4E2D",
|
|
19492
|
+
removeBtn: "\u79FB\u9664",
|
|
19493
|
+
spec: "\u89C4\u683C",
|
|
19494
|
+
whyUnbridged: "\u4E3A\u4EC0\u4E48\u672A\u6865\u63A5\uFF1F",
|
|
19495
|
+
whyUnbridgedDesc: "\u6B64\u89C4\u683C\u5B58\u5728\u4E8E\u60A8\u7684 config.json \u4E2D\uFF0C\u4F46\u672A\u6865\u63A5\u5230\u5B9E\u65F6\u4F1A\u8BDD\u3002MCP \u670D\u52A1\u5668\u5728 reasonix code \u542F\u52A8\u65F6\u8FDE\u63A5\uFF1B\u4EEA\u8868\u76D8\u672C\u8EAB\u65E0\u6CD5\u751F\u6210\u5B50\u8FDB\u7A0B\u3002",
|
|
19496
|
+
whyUnbridgedHint: "\u6FC0\u6D3B\u65B9\u6CD5\uFF1A\u91CD\u542F reasonix code\uFF0C\u7136\u540E\u5237\u65B0\u6B64\u4EEA\u8868\u76D8\u3002",
|
|
19497
|
+
pickHint: "\u9009\u62E9\u5DE6\u4FA7\u7684 MCP \u670D\u52A1\u5668\u4EE5\u68C0\u67E5\u5DE5\u5177 / \u8D44\u6E90 / \u63D0\u793A\u3002",
|
|
19498
|
+
toolsTitle: "\u5DE5\u5177 \xB7 {count}",
|
|
19499
|
+
resourcesTitle: "\u8D44\u6E90 \xB7 {count}",
|
|
19500
|
+
promptsTitle: "\u63D0\u793A \xB7 {count}",
|
|
19501
|
+
colName: "\u540D\u79F0",
|
|
19502
|
+
colDesc: "\u63CF\u8FF0",
|
|
19503
|
+
colUri: "URI"
|
|
19504
|
+
},
|
|
19505
|
+
memory: {
|
|
19506
|
+
loading: "\u52A0\u8F7D\u8BB0\u5FC6\u2026",
|
|
19507
|
+
files: "\u8BB0\u5FC6 \xB7 {count} \u4E2A\u6587\u4EF6",
|
|
19508
|
+
exists: "\u5DF2\u5B58\u5728",
|
|
19509
|
+
create: "\u521B\u5EFA",
|
|
19510
|
+
noFiles: "\u6682\u65E0\u8BB0\u5FC6\u6587\u4EF6\u3002",
|
|
19511
|
+
pickHint: "\u9009\u62E9\u5DE6\u4FA7\u7684\u8BB0\u5FC6\u6587\u4EF6\u3002",
|
|
19512
|
+
pickDesc: "\u9879\u76EE REASONIX.md \u53EF\u63D0\u4EA4\uFF1B\u5168\u5C40\u7B14\u8BB0\u5B58\u50A8\u5728 ~/.reasonix/memory/\u3002",
|
|
19513
|
+
chars: "{count} \u4E2A\u5B57\u7B26",
|
|
19514
|
+
saved: "\u5DF2\u4FDD\u5B58 {scope}",
|
|
19515
|
+
reloadHint: "\u5728\u4E0B\u6B21 /new \u6216\u4F1A\u8BDD\u91CD\u542F\u65F6\u91CD\u65B0\u52A0\u8F7D"
|
|
19516
|
+
},
|
|
19517
|
+
hooks: {
|
|
19518
|
+
loading: "\u52A0\u8F7D\u94A9\u5B50\u2026",
|
|
19519
|
+
resolved: "\u5DF2\u89E3\u6790",
|
|
19520
|
+
eventMatrix: "\u4E8B\u4EF6\u77E9\u9635",
|
|
19521
|
+
matrixSub: "{scripts} \u4E2A\u811A\u672C \xD7 {events} \u4E2A\u4E8B\u4EF6",
|
|
19522
|
+
noHooks: "\u672A\u914D\u7F6E\u94A9\u5B50\u3002\u7F16\u8F91\u4E0B\u65B9\u7684 JSON \u4EE5\u6DFB\u52A0\u3002",
|
|
19523
|
+
colScript: "\u811A\u672C",
|
|
19524
|
+
noProject: "\u65E0\u6D3B\u8DC3\u9879\u76EE \u2014 \u5728 reasonix code \u4E2D\u6253\u5F00 /dashboard \u4EE5\u7F16\u8F91\u9879\u76EE\u94A9\u5B50\u3002",
|
|
19525
|
+
saveReload: "\u4FDD\u5B58\u5E76\u91CD\u8F7D",
|
|
19526
|
+
discard: "\u653E\u5F03\u66F4\u6539",
|
|
19527
|
+
savedReloaded: "\u5DF2\u4FDD\u5B58\u5E76\u91CD\u8F7D {scope}",
|
|
19528
|
+
recentRuns: "\u8FD1\u671F\u8FD0\u884C",
|
|
19529
|
+
noRuns: "\u8FD1\u671F\u4F1A\u8BDD\u65E5\u5FD7\u4E2D\u65E0\u94A9\u5B50\u8FD0\u884C\u8BB0\u5F55\u3002",
|
|
19530
|
+
colWhen: "\u65F6\u95F4",
|
|
19531
|
+
colPhase: "\u9636\u6BB5",
|
|
19532
|
+
colHook: "\u94A9\u5B50",
|
|
19533
|
+
colOutcome: "\u7ED3\u679C"
|
|
19534
|
+
},
|
|
19535
|
+
skills: {
|
|
19536
|
+
loading: "\u52A0\u8F7D\u6280\u80FD\u2026",
|
|
19537
|
+
filterPlaceholder: "\u7B5B\u9009\u6280\u80FD",
|
|
19538
|
+
project: "\u9879\u76EE",
|
|
19539
|
+
global: "\u5168\u5C40",
|
|
19540
|
+
builtin: "\u5185\u7F6E",
|
|
19541
|
+
newSkill: "\u65B0\u6280\u80FD",
|
|
19542
|
+
noDescription: "\uFF08\u65E0\u63CF\u8FF0\uFF09",
|
|
19543
|
+
runs7d: "\u6B21\u8FD0\u884C \xB7 7 \u5929",
|
|
19544
|
+
pickHint: "\u9009\u62E9\u5DE6\u4FA7\u7684\u6280\u80FD\uFF0C\u6216\u5728\u4E0A\u65B9\u521B\u5EFA\u65B0\u6280\u80FD\u3002",
|
|
19545
|
+
readOnlyBuiltin: "\u53EA\u8BFB \xB7 \u5185\u7F6E",
|
|
19546
|
+
builtinDesc: "\u5185\u7F6E\u6280\u80FD\u968F Reasonix \u4E00\u8D77\u53D1\u5E03\uFF1B\u6A21\u578B\u4F1A\u81EA\u52A8\u8BC6\u522B\u3002\u5982\u9700\u81EA\u5B9A\u4E49\uFF0C\u8BF7\u521B\u5EFA\u540C\u540D\u7684\u9879\u76EE\u6216\u5168\u5C40\u6280\u80FD\u3002",
|
|
19547
|
+
saved: "\u5DF2\u4FDD\u5B58 {scope}/{name}",
|
|
19548
|
+
deleteConfirm: "\u5220\u9664\u6280\u80FD {scope}/{name}\uFF1F",
|
|
19549
|
+
reloadHint: "\u5728\u4E0B\u6B21 /new \u6216\u4F1A\u8BDD\u91CD\u542F\u65F6\u91CD\u65B0\u52A0\u8F7D"
|
|
19550
|
+
},
|
|
19551
|
+
system: {
|
|
19552
|
+
loading: "\u52A0\u8F7D\u5065\u5EB7\u72B6\u6001\u2026",
|
|
19553
|
+
failed: "\u5065\u5EB7\u68C0\u67E5\u5931\u8D25\uFF1A{error}",
|
|
19554
|
+
healthChecks: "\u5065\u5EB7\u68C0\u67E5",
|
|
19555
|
+
version: "\u7248\u672C",
|
|
19556
|
+
checking: "\u68C0\u67E5\u4E2D",
|
|
19557
|
+
latest: "\u25CF \u6700\u65B0",
|
|
19558
|
+
outOfDate: "\u25CF \u9700\u8981\u66F4\u65B0",
|
|
19559
|
+
versionPending: "\u7248\u672C\u68C0\u67E5\u4E2D",
|
|
19560
|
+
upToDate: "\u5DF2\u662F\u6700\u65B0",
|
|
19561
|
+
latestVer: "\u6700\u65B0\uFF1A{version}",
|
|
19562
|
+
sessions: "\u4F1A\u8BDD",
|
|
19563
|
+
ok: "\u25CF \u6B63\u5E38",
|
|
19564
|
+
memory: "\u8BB0\u5FC6",
|
|
19565
|
+
semanticIndex: "\u8BED\u4E49\u7D22\u5F15",
|
|
19566
|
+
built: "\u25CF \u5DF2\u6784\u5EFA",
|
|
19567
|
+
none: "\u2014 \u65E0",
|
|
19568
|
+
runIndex: "\u8FD0\u884C reasonix index \u4EE5\u6784\u5EFA",
|
|
19569
|
+
usageLog: "\u7528\u91CF\u65E5\u5FD7",
|
|
19570
|
+
backgroundJobs: "\u540E\u53F0\u4EFB\u52A1",
|
|
19571
|
+
noSession: "\u2014 \u65E0\u4F1A\u8BDD",
|
|
19572
|
+
running: "{count} \u4E2A\u8FD0\u884C\u4E2D",
|
|
19573
|
+
attachHint: "\u8FDE\u63A5\u4F1A\u8BDD\u4EE5\u67E5\u770B\u4EFB\u52A1",
|
|
19574
|
+
shellSpawn: "Shell + \u751F\u6210",
|
|
19575
|
+
paths: "\u8DEF\u5F84",
|
|
19576
|
+
home: "\u4E3B\u76EE\u5F55",
|
|
19577
|
+
sessionsPath: "\u4F1A\u8BDD",
|
|
19578
|
+
memoryPath: "\u8BB0\u5FC6",
|
|
19579
|
+
semanticPath: "\u8BED\u4E49",
|
|
19580
|
+
usagePath: "\u7528\u91CF"
|
|
19581
|
+
},
|
|
19582
|
+
plans: {
|
|
19583
|
+
loading: "\u52A0\u8F7D\u8BA1\u5212\u2026",
|
|
19584
|
+
failed: "\u8BA1\u5212\u5931\u8D25\uFF1A{error}",
|
|
19585
|
+
noPlans: "\u6682\u65E0\u5F52\u6863\u8BA1\u5212 \u2014 \u8FD0\u884C\u8C03\u7528 submit_plan \u548C mark_step_complete \u7684\u8F6E\u6B21\u3002",
|
|
19586
|
+
filterPlaceholder: "\u7B5B\u9009\u8BA1\u5212",
|
|
19587
|
+
active: "\u8FDB\u884C\u4E2D",
|
|
19588
|
+
done: "\u5DF2\u5B8C\u6210",
|
|
19589
|
+
steps: "\u6B65\u9AA4",
|
|
19590
|
+
pickHint: "\u9009\u62E9\u5DE6\u4FA7\u7684\u8BA1\u5212\u3002",
|
|
19591
|
+
noTitle: "\uFF08\u65E0\u6807\u9898\uFF09",
|
|
19592
|
+
stepTimeline: "\u6B65\u9AA4\u65F6\u95F4\u7EBF \xB7 {done} / {total}",
|
|
19593
|
+
step: "\u6B65\u9AA4 {n}"
|
|
19594
|
+
},
|
|
19595
|
+
semantic: {
|
|
19596
|
+
codeRequired: "\u8BED\u4E49 \u2014 \u9700\u8981\u4EE3\u7801\u6A21\u5F0F",
|
|
19597
|
+
indexBuilt: "\u7D22\u5F15\u5DF2\u6784\u5EFA",
|
|
19598
|
+
noIndex: "\u5C1A\u65E0\u7D22\u5F15",
|
|
19599
|
+
ready: "\u5C31\u7EEA",
|
|
19600
|
+
setupNeeded: "\u9700\u8981\u8BBE\u7F6E",
|
|
19601
|
+
installOllama: "\u5B89\u88C5 Ollama",
|
|
19602
|
+
installOllamaDesc: "Reasonix \u4E0D\u4F1A\u4E3A\u60A8\u8FD0\u884C\u5305\u7BA1\u7406\u5668\u3002\u8BF7\u5148\u5B89\u88C5 Ollama\uFF0C\u7136\u540E\u8FD4\u56DE\uFF1A",
|
|
19603
|
+
macWindows: "macOS / Windows\uFF1A",
|
|
19604
|
+
download: "\u4ECE ollama.com/download \u4E0B\u8F7D",
|
|
19605
|
+
linux: "Linux\uFF1A",
|
|
19606
|
+
refreshHint: "\u5B89\u88C5\u540E\u5237\u65B0 \u2014 \u6B64\u9762\u677F\u5C06\u63D0\u4F9B\u542F\u52A8\u5B88\u62A4\u8FDB\u7A0B\u548C\u62C9\u53D6 {model} \u7684\u9009\u9879\u3002",
|
|
19607
|
+
daemon: "\u5B88\u62A4\u8FDB\u7A0B",
|
|
19608
|
+
daemonDesc: "ollama \u5728\u60A8\u7684 PATH \u4E2D\uFF0C\u4F46 HTTP \u5B88\u62A4\u8FDB\u7A0B\u4E0D\u53EF\u8FBE\u3002",
|
|
19609
|
+
startDaemon: "\u542F\u52A8\u5B88\u62A4\u8FDB\u7A0B",
|
|
19610
|
+
runsOllama: "\u4EE5\u5206\u79BB\u6A21\u5F0F\u8FD0\u884C ollama serve",
|
|
19611
|
+
model: "\u6A21\u578B",
|
|
19612
|
+
modelMissing: "{model} \u5C1A\u672A\u5B89\u88C5\u3002",
|
|
19613
|
+
modelSize: "\u9996\u6B21\u62C9\u53D6\u7EA6 270 MB\u3002",
|
|
19614
|
+
pulling: "\u62C9\u53D6\u4E2D\u2026",
|
|
19615
|
+
pullModel: "\u62C9\u53D6 {model}",
|
|
19616
|
+
indexStatus: "\u7D22\u5F15\u72B6\u6001",
|
|
19617
|
+
builtStatus: "\u25CF \u5DF2\u6784\u5EFA",
|
|
19618
|
+
chunks: "\u5206\u5757",
|
|
19619
|
+
files: "\u6587\u4EF6",
|
|
19620
|
+
dim: "\u7EF4\u5EA6",
|
|
19621
|
+
size: "\u5927\u5C0F",
|
|
19622
|
+
lastBuild: "\u4E0A\u6B21\u6784\u5EFA",
|
|
19623
|
+
runIndexHint: "\u8FD0\u884C\u7D22\u5F15\u4EE5\u542F\u7528 semantic_search\u3002",
|
|
19624
|
+
reIndex: "\u91CD\u5EFA\u7D22\u5F15",
|
|
19625
|
+
build: "\u6784\u5EFA",
|
|
19626
|
+
rebuild: "\u5B8C\u5168\u91CD\u5EFA",
|
|
19627
|
+
stop: "\u505C\u6B62",
|
|
19628
|
+
ollama: "Ollama",
|
|
19629
|
+
binary: "\u4E8C\u8FDB\u5236",
|
|
19630
|
+
found: "\u5DF2\u627E\u5230",
|
|
19631
|
+
missing: "\u7F3A\u5931",
|
|
19632
|
+
daemonStatus: "\u5B88\u62A4\u8FDB\u7A0B",
|
|
19633
|
+
up: "\u8FD0\u884C\u4E2D",
|
|
19634
|
+
down: "\u5DF2\u505C\u6B62",
|
|
19635
|
+
pulled: "\u5DF2\u62C9\u53D6",
|
|
19636
|
+
indexConfig: "\u7D22\u5F15\u914D\u7F6E",
|
|
19637
|
+
reset: "\u91CD\u7F6E",
|
|
19638
|
+
excludeDirs: "\u6392\u9664\u76EE\u5F55",
|
|
19639
|
+
excludeFiles: "\u6392\u9664\u6587\u4EF6",
|
|
19640
|
+
excludeExts: "\u6392\u9664\u6269\u5C55\u540D",
|
|
19641
|
+
excludePatterns: "\u6392\u9664\u6A21\u5F0F",
|
|
19642
|
+
glob: "glob",
|
|
19643
|
+
respectGitignore: "\u9075\u5FAA .gitignore",
|
|
19644
|
+
maxFileBytes: "\u6700\u5927\u6587\u4EF6\u5B57\u8282\u6570",
|
|
19645
|
+
skipLarger: "\u8DF3\u8FC7\u5927\u4E8E ~{size} MiB \u7684\u6587\u4EF6",
|
|
19646
|
+
preview: "\u9884\u89C8",
|
|
19647
|
+
searchPlaceholder: "\u63CF\u8FF0\u8981\u67E5\u627E\u7684\u5185\u5BB9 \u2014 '\u54EA\u91CC\u5904\u7406\u4E2D\u6B62\u4FE1\u53F7'",
|
|
19648
|
+
searching: "\u641C\u7D22\u4E2D\u2026",
|
|
19649
|
+
results: "{count} \u4E2A\u7ED3\u679C \xB7 {ms}ms \xB7 {model}",
|
|
19650
|
+
noMatches: "\u6CA1\u6709\u8D85\u8FC7\u5206\u6570\u9608\u503C\u7684\u5339\u914D\u3002",
|
|
19651
|
+
previewSummary: "\u9884\u89C8 \u2014 \u5C06\u7D22\u5F15 {included} \u4E2A\u6587\u4EF6\uFF0C\u8DF3\u8FC7 {skipped} \u4E2A",
|
|
19652
|
+
nothingSkipped: "\u65E0\u8DF3\u8FC7 \u2014 \u6240\u6709\u904D\u5386\u7684\u6587\u4EF6\u90FD\u5C06\u88AB\u7D22\u5F15\u3002",
|
|
19653
|
+
firstIncluded: "\u524D {count} \u4E2A\u5305\u542B\u7684\u6587\u4EF6",
|
|
19654
|
+
job: "\u4EFB\u52A1",
|
|
19655
|
+
phaseScan: "\u626B\u63CF\u6587\u4EF6",
|
|
19656
|
+
phaseEmbed: "\u5D4C\u5165\u5206\u5757",
|
|
19657
|
+
phaseWrite: "\u5199\u5165\u7D22\u5F15",
|
|
19658
|
+
phaseDone: "\u5B8C\u6210",
|
|
19659
|
+
phaseError: "\u9519\u8BEF",
|
|
19660
|
+
stopping: "\u505C\u6B62\u4E2D",
|
|
19661
|
+
scanned: "\u5DF2\u626B\u63CF {count}",
|
|
19662
|
+
changed: "\u5DF2\u53D8\u66F4 {count}",
|
|
19663
|
+
skipped: "\u5DF2\u8DF3\u8FC7 {count}",
|
|
19664
|
+
chunksProgress: "{done} / {total}\uFF08{pct}%\uFF09",
|
|
19665
|
+
result: "\u7ED3\u679C",
|
|
19666
|
+
added: "\u5DF2\u6DFB\u52A0 {count}",
|
|
19667
|
+
removed: "\u5DF2\u79FB\u9664 {count}",
|
|
19668
|
+
failed: "\u5931\u8D25 {count}",
|
|
19669
|
+
skippedFiles: "{total} \u4E2A\u6587\u4EF6\uFF08{details}\uFF09",
|
|
19670
|
+
rebuildStarted: "\u5DF2\u542F\u52A8\u5B8C\u5168\u91CD\u5EFA",
|
|
19671
|
+
incrementalStarted: "\u5DF2\u542F\u52A8\u589E\u91CF\u7D22\u5F15",
|
|
19672
|
+
stopRequested: "\u5DF2\u8BF7\u6C42\u505C\u6B62 \u2014 \u5F53\u524D\u5206\u5757\u6279\u6B21\u5C06\u9996\u5148\u5B8C\u6210",
|
|
19673
|
+
startingDaemon: "\u6B63\u5728\u542F\u52A8 ollama \u5B88\u62A4\u8FDB\u7A0B\uFF0815 \u79D2\u8D85\u65F6\uFF09\u2026",
|
|
19674
|
+
daemonUp: "\u5B88\u62A4\u8FDB\u7A0B\u5DF2\u542F\u52A8",
|
|
19675
|
+
daemonTimeout: "\u5B88\u62A4\u8FDB\u7A0B\u672A\u5728\u89C4\u5B9A\u65F6\u95F4\u5185\u542F\u52A8 \u2014 \u8BF7\u624B\u52A8\u68C0\u67E5 ollama serve",
|
|
19676
|
+
pullingModel: "\u6B63\u5728\u62C9\u53D6 {model} \u2014 \u9996\u6B21\u5B89\u88C5\u53EF\u80FD\u9700\u8981\u51E0\u5206\u949F",
|
|
19677
|
+
savedConfig: "\u5DF2\u4FDD\u5B58 \xB7 {count} \u4E2A\u5B57\u6BB5\u5DF2\u66F4\u65B0 \xB7 \u91CD\u65B0\u8FD0\u884C\u7D22\u5F15\u4EE5\u5E94\u7528",
|
|
19678
|
+
runningPreview: "\u6B63\u5728\u5BF9\u9879\u76EE\u6839\u76EE\u5F55\u6267\u884C\u5E72\u8FD0\u884C\u2026",
|
|
19679
|
+
exclude: "\u6392\u9664"
|
|
19680
|
+
},
|
|
19681
|
+
modal: {
|
|
19682
|
+
shellTitle: "Shell \u547D\u4EE4",
|
|
19683
|
+
shellBgTitle: "\u540E\u53F0\u8FDB\u7A0B",
|
|
19684
|
+
shellSubtitle: "\u6A21\u578B\u60F3\u8981\u8FD0\u884C\u4E00\u6761 Shell \u547D\u4EE4",
|
|
19685
|
+
shellBgSubtitle: "\u957F\u65F6\u95F4\u8FD0\u884C \u2014 \u6279\u51C6\u540E\u7EE7\u7EED\u8FD0\u884C",
|
|
19686
|
+
runOnce: "\u8FD0\u884C\u4E00\u6B21",
|
|
19687
|
+
alwaysAllow: '\u59CB\u7EC8\u5141\u8BB8 "{prefix}"',
|
|
19688
|
+
deny: "\u62D2\u7EDD",
|
|
19689
|
+
choiceTitle: "\u6A21\u578B\u9700\u8981\u60A8\u9009\u62E9",
|
|
19690
|
+
typeOwn: "\u8F93\u5165\u81EA\u5B9A\u4E49\u56DE\u7B54",
|
|
19691
|
+
typeOwnSummary: "\u4EE5\u4E0A\u9009\u9879\u90FD\u4E0D\u5408\u9002 \u2014 \u5199\u4E00\u4E2A\u81EA\u7531\u683C\u5F0F\u7684\u56DE\u590D\u3002",
|
|
19692
|
+
typePlaceholder: "\u8F93\u5165\u81EA\u7531\u683C\u5F0F\u7684\u56DE\u7B54\u2026",
|
|
19693
|
+
send: "\u53D1\u9001",
|
|
19694
|
+
cancel: "\u53D6\u6D88",
|
|
19695
|
+
cancelSummary: "\u653E\u5F03\u6B64\u95EE\u9898\u3002\u6A21\u578B\u5C06\u8BE2\u95EE\u60A8\u5B9E\u9645\u60F3\u8981\u4EC0\u4E48\u3002",
|
|
19696
|
+
planTitle: "\u8BA1\u5212\u5DF2\u63D0\u4EA4",
|
|
19697
|
+
planSubtitle: "\u6A21\u578B\u63D0\u51FA\u4E86\u4E00\u9879\u8BA1\u5212\uFF1B\u8BF7\u5BA1\u9605\u540E\u9009\u62E9",
|
|
19698
|
+
approveInstructions: "\u53EF\u9009\u7684\u6700\u540E\u6307\u793A / \u5BF9\u5F00\u653E\u95EE\u9898\u7684\u56DE\u7B54\uFF08Enter \u53D1\u9001\u7A7A\u767D\uFF09",
|
|
19699
|
+
refinePlaceholder: "\u9700\u8981\u66F4\u6539\u4EC0\u4E48\uFF1F\u8BF7\u5177\u4F53\u8BF4\u660E\u3002",
|
|
19700
|
+
approve: "\u6279\u51C6",
|
|
19701
|
+
refine: "\u4F18\u5316",
|
|
19702
|
+
sendRefinement: "\u53D1\u9001\u4F18\u5316",
|
|
19703
|
+
editTitle: "\u7F16\u8F91\u5F85\u5BA1\u9605",
|
|
19704
|
+
editSubtitle: "{path} \xB7 {remaining} / {total} \u4E2A\u5757\u5269\u4F59",
|
|
19705
|
+
before: "\u4FEE\u6539\u524D",
|
|
19706
|
+
after: "\u4FEE\u6539\u540E",
|
|
19707
|
+
workspaceTitle: "\u6A21\u578B\u60F3\u8981\u5207\u6362\u5DE5\u4F5C\u533A",
|
|
19708
|
+
workspaceSubtitle: "\u540E\u7EED\u6240\u6709\u6587\u4EF6 / Shell / \u8BB0\u5FC6\u5DE5\u5177\u5C06\u9488\u5BF9\u65B0\u6839\u76EE\u5F55\u89E3\u6790",
|
|
19709
|
+
switchBtn: "\u5207\u6362 (Enter)",
|
|
19710
|
+
denyBtn: "\u62D2\u7EDD (Esc)",
|
|
19711
|
+
stepComplete: "\u6B65\u9AA4\u5B8C\u6210{counter}",
|
|
19712
|
+
continueBtn: "\u7EE7\u7EED",
|
|
19713
|
+
reviseBtn: "\u4FEE\u8BA2\u2026",
|
|
19714
|
+
stopBtn: "\u505C\u6B62",
|
|
19715
|
+
revisionTitle: "\u6A21\u578B\u63D0\u51FA\u4E86\u8BA1\u5212\u4FEE\u8BA2",
|
|
19716
|
+
sendRevision: "\u53D1\u9001\u4FEE\u8BA2",
|
|
19717
|
+
accept: "\u63A5\u53D7",
|
|
19718
|
+
reject: "\u62D2\u7EDD",
|
|
19719
|
+
arguments: "\u53C2\u6570",
|
|
19720
|
+
revisePlaceholder: "\u4E0B\u4E00\u6B65\u4E4B\u524D\u9700\u8981\u66F4\u6539\u4EC0\u4E48\uFF1F\u7559\u7A7A\u5219\u76F4\u63A5\u7EE7\u7EED\u3002"
|
|
19721
|
+
}
|
|
19722
|
+
};
|
|
19723
|
+
|
|
19724
|
+
// dashboard/src/i18n/index.ts
|
|
19725
|
+
var t4 = createT({ en, "zh-CN": zhCN });
|
|
19726
|
+
|
|
18639
19727
|
// node_modules/marked/lib/marked.esm.js
|
|
18640
19728
|
function _getDefaults() {
|
|
18641
19729
|
return {
|
|
@@ -18950,7 +20038,7 @@ var _Tokenizer = class {
|
|
|
18950
20038
|
}
|
|
18951
20039
|
raw = cap[0];
|
|
18952
20040
|
src = src.substring(raw.length);
|
|
18953
|
-
let line = cap[2].split("\n", 1)[0].replace(/^\t+/, (
|
|
20041
|
+
let line = cap[2].split("\n", 1)[0].replace(/^\t+/, (t5) => " ".repeat(3 * t5.length));
|
|
18954
20042
|
let nextLine = src.split("\n", 1)[0];
|
|
18955
20043
|
let indent = 0;
|
|
18956
20044
|
if (this.options.pedantic) {
|
|
@@ -19053,8 +20141,8 @@ var _Tokenizer = class {
|
|
|
19053
20141
|
this.lexer.state.top = false;
|
|
19054
20142
|
list2.items[i3].tokens = this.lexer.blockTokens(list2.items[i3].text, []);
|
|
19055
20143
|
if (!list2.loose) {
|
|
19056
|
-
const spacers = list2.items[i3].tokens.filter((
|
|
19057
|
-
const hasMultipleLineBreaks = spacers.length > 0 && spacers.some((
|
|
20144
|
+
const spacers = list2.items[i3].tokens.filter((t5) => t5.type === "space");
|
|
20145
|
+
const hasMultipleLineBreaks = spacers.length > 0 && spacers.some((t5) => /\n.*\n/.test(t5.raw));
|
|
19058
20146
|
list2.loose = hasMultipleLineBreaks;
|
|
19059
20147
|
}
|
|
19060
20148
|
}
|
|
@@ -20817,6 +21905,7 @@ function parseToolArgs(raw) {
|
|
|
20817
21905
|
}
|
|
20818
21906
|
}
|
|
20819
21907
|
function ToolCard({ msg }) {
|
|
21908
|
+
useLang();
|
|
20820
21909
|
const args = parseToolArgs(msg.toolArgs);
|
|
20821
21910
|
const name = msg.toolName ?? "tool";
|
|
20822
21911
|
const path = args?.path ?? args?.file_path ?? args?.filename;
|
|
@@ -20898,7 +21987,7 @@ function ToolCard({ msg }) {
|
|
|
20898
21987
|
<span class="tool-card-icon">▣</span>
|
|
20899
21988
|
<span class="tool-card-name">${name}</span>
|
|
20900
21989
|
</div>
|
|
20901
|
-
${args ? html4`<details class="tool-card-args"><summary
|
|
21990
|
+
${args ? html4`<details class="tool-card-args"><summary>${t4("modal.arguments")}</summary><pre>${escapeHtml(JSON.stringify(args, null, 2))}</pre></details>` : null}
|
|
20902
21991
|
<pre class="tool-card-output">${msg.text}</pre>
|
|
20903
21992
|
</div>
|
|
20904
21993
|
`;
|
|
@@ -20940,28 +22029,30 @@ function ModalCard({ accent, icon, title, subtitle, children }) {
|
|
|
20940
22029
|
`;
|
|
20941
22030
|
}
|
|
20942
22031
|
function ShellModal({ modal, onResolve }) {
|
|
22032
|
+
useLang();
|
|
20943
22033
|
const isBg = modal.shellKind === "run_background";
|
|
20944
22034
|
return html4`
|
|
20945
22035
|
<${ModalCard}
|
|
20946
22036
|
accent="#f87171"
|
|
20947
22037
|
icon=${isBg ? "\u23F1" : "\u26A1"}
|
|
20948
|
-
title=${isBg ? "
|
|
20949
|
-
subtitle=${isBg ? "
|
|
22038
|
+
title=${isBg ? t4("modal.shellBgTitle") : t4("modal.shellTitle")}
|
|
22039
|
+
subtitle=${isBg ? t4("modal.shellBgSubtitle") : t4("modal.shellSubtitle")}
|
|
20950
22040
|
>
|
|
20951
22041
|
<div class="modal-cmd"><span class="modal-cmd-prompt">$</span> <code>${modal.command}</code></div>
|
|
20952
22042
|
<div class="modal-actions">
|
|
20953
|
-
<button class="primary" onClick=${() => onResolve("shell", "run_once")}
|
|
20954
|
-
<button onClick=${() => onResolve("shell", "always_allow")}
|
|
20955
|
-
<button class="danger" onClick=${() => onResolve("shell", "deny")}
|
|
22043
|
+
<button class="primary" onClick=${() => onResolve("shell", "run_once")}>${t4("modal.runOnce")}</button>
|
|
22044
|
+
<button onClick=${() => onResolve("shell", "always_allow")}>${t4("modal.alwaysAllow", { prefix: modal.allowPrefix ?? "" })}</button>
|
|
22045
|
+
<button class="danger" onClick=${() => onResolve("shell", "deny")}>${t4("modal.deny")}</button>
|
|
20956
22046
|
</div>
|
|
20957
22047
|
<//>
|
|
20958
22048
|
`;
|
|
20959
22049
|
}
|
|
20960
22050
|
function ChoiceModal({ modal, onResolve }) {
|
|
22051
|
+
useLang();
|
|
20961
22052
|
const [custom, setCustom] = p2("");
|
|
20962
22053
|
const [showCustom, setShowCustom] = p2(false);
|
|
20963
22054
|
return html4`
|
|
20964
|
-
<${ModalCard} accent="#f0abfc" icon="🔀" title
|
|
22055
|
+
<${ModalCard} accent="#f0abfc" icon="🔀" title=${t4("modal.choiceTitle")} subtitle=${modal.question}>
|
|
20965
22056
|
${modal.options.map(
|
|
20966
22057
|
(opt) => html4`
|
|
20967
22058
|
<button
|
|
@@ -20978,60 +22069,61 @@ function ChoiceModal({ modal, onResolve }) {
|
|
|
20978
22069
|
${modal.allowCustom ? showCustom ? html4`
|
|
20979
22070
|
<div class="modal-custom">
|
|
20980
22071
|
<textarea
|
|
20981
|
-
placeholder
|
|
22072
|
+
placeholder=${t4("modal.typePlaceholder")}
|
|
20982
22073
|
rows="2"
|
|
20983
22074
|
value=${custom}
|
|
20984
22075
|
onInput=${(e3) => setCustom(e3.target.value)}
|
|
20985
22076
|
></textarea>
|
|
20986
22077
|
<div class="modal-actions">
|
|
20987
|
-
<button class="primary" onClick=${() => onResolve("choice", { kind: "custom", text: custom })} disabled=${!custom.trim()}
|
|
22078
|
+
<button class="primary" onClick=${() => onResolve("choice", { kind: "custom", text: custom })} disabled=${!custom.trim()}>${t4("modal.send")}</button>
|
|
20988
22079
|
<button onClick=${() => {
|
|
20989
22080
|
setShowCustom(false);
|
|
20990
22081
|
setCustom("");
|
|
20991
|
-
}}
|
|
22082
|
+
}}>${t4("common.back")}</button>
|
|
20992
22083
|
</div>
|
|
20993
22084
|
</div>
|
|
20994
22085
|
` : html4`
|
|
20995
22086
|
<button class="modal-choice-row" onClick=${() => setShowCustom(true)}>
|
|
20996
22087
|
<span class="modal-choice-id">·</span>
|
|
20997
|
-
<span class="modal-choice-title"
|
|
20998
|
-
<span class="modal-choice-summary"
|
|
22088
|
+
<span class="modal-choice-title">${t4("modal.typeOwn")}</span>
|
|
22089
|
+
<span class="modal-choice-summary">${t4("modal.typeOwnSummary")}</span>
|
|
20999
22090
|
</button>
|
|
21000
22091
|
` : null}
|
|
21001
22092
|
<button class="modal-choice-row modal-choice-cancel" onClick=${() => onResolve("choice", { kind: "cancel" })}>
|
|
21002
22093
|
<span class="modal-choice-id">×</span>
|
|
21003
|
-
<span class="modal-choice-title"
|
|
21004
|
-
<span class="modal-choice-summary"
|
|
22094
|
+
<span class="modal-choice-title">${t4("modal.cancel")}</span>
|
|
22095
|
+
<span class="modal-choice-summary">${t4("modal.cancelSummary")}</span>
|
|
21005
22096
|
</button>
|
|
21006
22097
|
<//>
|
|
21007
22098
|
`;
|
|
21008
22099
|
}
|
|
21009
22100
|
function PlanModal({ modal, onResolve }) {
|
|
22101
|
+
useLang();
|
|
21010
22102
|
const [feedback, setFeedback] = p2("");
|
|
21011
22103
|
const [stage, setStage] = p2(null);
|
|
21012
22104
|
const send = () => onResolve("plan", stage, feedback);
|
|
21013
22105
|
return html4`
|
|
21014
|
-
<${ModalCard} accent="#67e8f9" icon="◆" title
|
|
22106
|
+
<${ModalCard} accent="#67e8f9" icon="◆" title=${t4("modal.planTitle")} subtitle=${t4("modal.planSubtitle")}>
|
|
21015
22107
|
<div class="md modal-plan-body" dangerouslySetInnerHTML=${{ __html: marked.parse(modal.body || "") }}></div>
|
|
21016
22108
|
${stage ? html4`
|
|
21017
22109
|
<textarea
|
|
21018
|
-
placeholder=${stage === "approve" ? "
|
|
22110
|
+
placeholder=${stage === "approve" ? t4("modal.approveInstructions") : t4("modal.refinePlaceholder")}
|
|
21019
22111
|
rows="3"
|
|
21020
22112
|
value=${feedback}
|
|
21021
22113
|
onInput=${(e3) => setFeedback(e3.target.value)}
|
|
21022
22114
|
></textarea>
|
|
21023
22115
|
<div class="modal-actions">
|
|
21024
|
-
<button class="primary" onClick=${send}>${stage === "approve" ? "
|
|
22116
|
+
<button class="primary" onClick=${send}>${stage === "approve" ? t4("modal.approve") : t4("modal.sendRefinement")}</button>
|
|
21025
22117
|
<button onClick=${() => {
|
|
21026
22118
|
setStage(null);
|
|
21027
22119
|
setFeedback("");
|
|
21028
|
-
}}
|
|
22120
|
+
}}>${t4("common.back")}</button>
|
|
21029
22121
|
</div>
|
|
21030
22122
|
` : html4`
|
|
21031
22123
|
<div class="modal-actions">
|
|
21032
|
-
<button class="primary" onClick=${() => setStage("approve")}
|
|
21033
|
-
<button onClick=${() => setStage("refine")}
|
|
21034
|
-
<button class="danger" onClick=${() => onResolve("plan", "cancel")}
|
|
22124
|
+
<button class="primary" onClick=${() => setStage("approve")}>${t4("modal.approve")}</button>
|
|
22125
|
+
<button onClick=${() => setStage("refine")}>${t4("modal.refine")}</button>
|
|
22126
|
+
<button class="danger" onClick=${() => onResolve("plan", "cancel")}>${t4("modal.cancel")}</button>
|
|
21035
22127
|
</div>
|
|
21036
22128
|
`}
|
|
21037
22129
|
<//>
|
|
@@ -21099,6 +22191,7 @@ function pairDiffRows(diff) {
|
|
|
21099
22191
|
return rows;
|
|
21100
22192
|
}
|
|
21101
22193
|
function EditReviewModal({ modal, onResolve }) {
|
|
22194
|
+
useLang();
|
|
21102
22195
|
const search = modal.search ?? "";
|
|
21103
22196
|
const replace = modal.replace ?? "";
|
|
21104
22197
|
const lang = langFromPath(modal.path);
|
|
@@ -21109,16 +22202,16 @@ function EditReviewModal({ modal, onResolve }) {
|
|
|
21109
22202
|
<${ModalCard}
|
|
21110
22203
|
accent="#86efac"
|
|
21111
22204
|
icon="◆"
|
|
21112
|
-
title
|
|
21113
|
-
subtitle=${
|
|
22205
|
+
title=${t4("modal.editTitle")}
|
|
22206
|
+
subtitle=${t4("modal.editSubtitle", { path: modal.path ?? "", remaining: modal.remaining, total: modal.total })}
|
|
21114
22207
|
>
|
|
21115
22208
|
<div class="edit-diff-wrap">
|
|
21116
22209
|
<div class="edit-diff-head">
|
|
21117
22210
|
<div class="edit-diff-side edit-diff-side-old">
|
|
21118
|
-
<span class="edit-diff-marker">−</span> before
|
|
22211
|
+
<span class="edit-diff-marker">−</span> ${t4("modal.before")}
|
|
21119
22212
|
</div>
|
|
21120
22213
|
<div class="edit-diff-side edit-diff-side-new">
|
|
21121
|
-
<span class="edit-diff-marker">+</span> after
|
|
22214
|
+
<span class="edit-diff-marker">+</span> ${t4("modal.after")}
|
|
21122
22215
|
</div>
|
|
21123
22216
|
</div>
|
|
21124
22217
|
<div class="edit-diff-body">
|
|
@@ -21143,31 +22236,33 @@ function EditReviewModal({ modal, onResolve }) {
|
|
|
21143
22236
|
</div>
|
|
21144
22237
|
</div>
|
|
21145
22238
|
<div class="modal-actions">
|
|
21146
|
-
<button class="primary" onClick=${() => onResolve("edit-review", "apply")}
|
|
21147
|
-
<button onClick=${() => onResolve("edit-review", "reject")}
|
|
21148
|
-
<button onClick=${() => onResolve("edit-review", "apply-rest-of-turn")}
|
|
21149
|
-
<button onClick=${() => onResolve("edit-review", "flip-to-auto")}
|
|
22239
|
+
<button class="primary" onClick=${() => onResolve("edit-review", "apply")}>${t4("chat.confirmBtn")}</button>
|
|
22240
|
+
<button onClick=${() => onResolve("edit-review", "reject")}>${t4("chat.rejectBtn")}</button>
|
|
22241
|
+
<button onClick=${() => onResolve("edit-review", "apply-rest-of-turn")}>${t4("chat.applyRestBtn")}</button>
|
|
22242
|
+
<button onClick=${() => onResolve("edit-review", "flip-to-auto")}>${t4("chat.flipAutoBtn")}</button>
|
|
21150
22243
|
</div>
|
|
21151
22244
|
<//>
|
|
21152
22245
|
`;
|
|
21153
22246
|
}
|
|
21154
22247
|
function WorkspaceModal({ modal, onResolve }) {
|
|
22248
|
+
useLang();
|
|
21155
22249
|
return html4`
|
|
21156
22250
|
<${ModalCard}
|
|
21157
22251
|
accent="#fbbf24"
|
|
21158
22252
|
icon="◇"
|
|
21159
|
-
title
|
|
21160
|
-
subtitle
|
|
22253
|
+
title=${t4("modal.workspaceTitle")}
|
|
22254
|
+
subtitle=${t4("modal.workspaceSubtitle")}
|
|
21161
22255
|
>
|
|
21162
22256
|
<div class="modal-cmd"><span class="modal-cmd-prompt">→</span> <code>${modal.path}</code></div>
|
|
21163
22257
|
<div class="modal-actions">
|
|
21164
|
-
<button class="primary" onClick=${() => onResolve("workspace", "switch")}
|
|
21165
|
-
<button class="danger" onClick=${() => onResolve("workspace", "deny")}
|
|
22258
|
+
<button class="primary" onClick=${() => onResolve("workspace", "switch")}>${t4("modal.switchBtn")}</button>
|
|
22259
|
+
<button class="danger" onClick=${() => onResolve("workspace", "deny")}>${t4("modal.denyBtn")}</button>
|
|
21166
22260
|
</div>
|
|
21167
22261
|
<//>
|
|
21168
22262
|
`;
|
|
21169
22263
|
}
|
|
21170
22264
|
function CheckpointModal({ modal, onResolve }) {
|
|
22265
|
+
useLang();
|
|
21171
22266
|
const [reviseText, setReviseText] = p2("");
|
|
21172
22267
|
const [staged, setStaged] = p2(false);
|
|
21173
22268
|
const label = modal.title ? `${modal.stepId} \xB7 ${modal.title}` : modal.stepId;
|
|
@@ -21176,40 +22271,41 @@ function CheckpointModal({ modal, onResolve }) {
|
|
|
21176
22271
|
<${ModalCard}
|
|
21177
22272
|
accent="#a5f3fc"
|
|
21178
22273
|
icon="✓"
|
|
21179
|
-
title=${
|
|
22274
|
+
title=${t4("modal.stepComplete", { counter })}
|
|
21180
22275
|
subtitle=${label}
|
|
21181
22276
|
>
|
|
21182
22277
|
${staged ? html4`
|
|
21183
22278
|
<textarea
|
|
21184
|
-
placeholder
|
|
22279
|
+
placeholder=${t4("modal.revisePlaceholder")}
|
|
21185
22280
|
rows="3"
|
|
21186
22281
|
value=${reviseText}
|
|
21187
22282
|
onInput=${(e3) => setReviseText(e3.target.value)}
|
|
21188
22283
|
></textarea>
|
|
21189
22284
|
<div class="modal-actions">
|
|
21190
|
-
<button class="primary" onClick=${() => onResolve("checkpoint", "revise", reviseText)}
|
|
22285
|
+
<button class="primary" onClick=${() => onResolve("checkpoint", "revise", reviseText)}>${t4("modal.sendRevision")}</button>
|
|
21191
22286
|
<button onClick=${() => {
|
|
21192
22287
|
setStaged(false);
|
|
21193
22288
|
setReviseText("");
|
|
21194
|
-
}}
|
|
22289
|
+
}}>${t4("common.back")}</button>
|
|
21195
22290
|
</div>
|
|
21196
22291
|
` : html4`
|
|
21197
22292
|
<div class="modal-actions">
|
|
21198
|
-
<button class="primary" onClick=${() => onResolve("checkpoint", "continue")}
|
|
21199
|
-
<button onClick=${() => setStaged(true)}
|
|
21200
|
-
<button class="danger" onClick=${() => onResolve("checkpoint", "stop")}
|
|
22293
|
+
<button class="primary" onClick=${() => onResolve("checkpoint", "continue")}>${t4("modal.continueBtn")}</button>
|
|
22294
|
+
<button onClick=${() => setStaged(true)}>${t4("modal.reviseBtn")}</button>
|
|
22295
|
+
<button class="danger" onClick=${() => onResolve("checkpoint", "stop")}>${t4("modal.stopBtn")}</button>
|
|
21201
22296
|
</div>
|
|
21202
22297
|
`}
|
|
21203
22298
|
<//>
|
|
21204
22299
|
`;
|
|
21205
22300
|
}
|
|
21206
22301
|
function RevisionModal({ modal, onResolve }) {
|
|
22302
|
+
useLang();
|
|
21207
22303
|
const riskColor = (r3) => r3 === "high" ? "#f87171" : r3 === "med" ? "#fbbf24" : r3 === "low" ? "#86efac" : "#9ca3af";
|
|
21208
22304
|
return html4`
|
|
21209
22305
|
<${ModalCard}
|
|
21210
22306
|
accent="#c4b5fd"
|
|
21211
22307
|
icon="✎"
|
|
21212
|
-
title
|
|
22308
|
+
title=${t4("modal.revisionTitle")}
|
|
21213
22309
|
subtitle=${modal.summary || modal.reason}
|
|
21214
22310
|
>
|
|
21215
22311
|
<div class="modal-revise-reason">${modal.reason}</div>
|
|
@@ -21226,8 +22322,8 @@ function RevisionModal({ modal, onResolve }) {
|
|
|
21226
22322
|
)}
|
|
21227
22323
|
</ol>
|
|
21228
22324
|
<div class="modal-actions">
|
|
21229
|
-
<button class="primary" onClick=${() => onResolve("revision", "accept")}
|
|
21230
|
-
<button class="danger" onClick=${() => onResolve("revision", "reject")}
|
|
22325
|
+
<button class="primary" onClick=${() => onResolve("revision", "accept")}>${t4("modal.accept")}</button>
|
|
22326
|
+
<button class="danger" onClick=${() => onResolve("revision", "reject")}>${t4("modal.reject")}</button>
|
|
21231
22327
|
</div>
|
|
21232
22328
|
<//>
|
|
21233
22329
|
`;
|
|
@@ -21281,6 +22377,7 @@ function fmtRelativeTime(iso) {
|
|
|
21281
22377
|
|
|
21282
22378
|
// dashboard/src/panels/chat.ts
|
|
21283
22379
|
function ChatPanel() {
|
|
22380
|
+
useLang();
|
|
21284
22381
|
const [messages, setMessages] = p2([]);
|
|
21285
22382
|
const [streaming, setStreaming] = p2(null);
|
|
21286
22383
|
const [activeTool, setActiveTool] = p2(null);
|
|
@@ -21436,7 +22533,7 @@ function ChatPanel() {
|
|
|
21436
22533
|
}
|
|
21437
22534
|
};
|
|
21438
22535
|
es.onerror = () => {
|
|
21439
|
-
setError("
|
|
22536
|
+
setError(t4("chat.eventStreamError"));
|
|
21440
22537
|
setTimeout(() => setError(null), 3e3);
|
|
21441
22538
|
};
|
|
21442
22539
|
return () => es.close();
|
|
@@ -21468,8 +22565,8 @@ function ChatPanel() {
|
|
|
21468
22565
|
}, []);
|
|
21469
22566
|
const newConversation = x2(async () => {
|
|
21470
22567
|
if (busy) {
|
|
21471
|
-
if (!confirm("
|
|
21472
|
-
} else if (messages.length > 0 && !confirm("
|
|
22568
|
+
if (!confirm(t4("chat.newConfirmBusy"))) return;
|
|
22569
|
+
} else if (messages.length > 0 && !confirm(t4("chat.newConfirm"))) {
|
|
21473
22570
|
return;
|
|
21474
22571
|
}
|
|
21475
22572
|
try {
|
|
@@ -21477,7 +22574,7 @@ function ChatPanel() {
|
|
|
21477
22574
|
setMessages([]);
|
|
21478
22575
|
setStreaming(null);
|
|
21479
22576
|
setActiveTool(null);
|
|
21480
|
-
showToast("
|
|
22577
|
+
showToast(t4("chat.newToast"), "info");
|
|
21481
22578
|
setTimeout(async () => {
|
|
21482
22579
|
try {
|
|
21483
22580
|
const r3 = await api("/messages");
|
|
@@ -21486,7 +22583,7 @@ function ChatPanel() {
|
|
|
21486
22583
|
}
|
|
21487
22584
|
}, 200);
|
|
21488
22585
|
} catch (err) {
|
|
21489
|
-
setError(
|
|
22586
|
+
setError(t4("chat.newFailed", { error: err.message }));
|
|
21490
22587
|
}
|
|
21491
22588
|
}, [busy, messages.length]);
|
|
21492
22589
|
const clearScrollback = x2(async () => {
|
|
@@ -21495,7 +22592,7 @@ function ChatPanel() {
|
|
|
21495
22592
|
setMessages([]);
|
|
21496
22593
|
setStreaming(null);
|
|
21497
22594
|
setActiveTool(null);
|
|
21498
|
-
showToast("
|
|
22595
|
+
showToast(t4("chat.clearToast"), "info");
|
|
21499
22596
|
setTimeout(async () => {
|
|
21500
22597
|
try {
|
|
21501
22598
|
const r3 = await api("/messages");
|
|
@@ -21504,7 +22601,7 @@ function ChatPanel() {
|
|
|
21504
22601
|
}
|
|
21505
22602
|
}, 200);
|
|
21506
22603
|
} catch (err) {
|
|
21507
|
-
setError(
|
|
22604
|
+
setError(t4("chat.clearFailed", { error: err.message }));
|
|
21508
22605
|
}
|
|
21509
22606
|
}, []);
|
|
21510
22607
|
const updatePopover = x2(
|
|
@@ -21602,7 +22699,7 @@ function ChatPanel() {
|
|
|
21602
22699
|
[send, popoverKind, popoverItems, applyPopover]
|
|
21603
22700
|
);
|
|
21604
22701
|
if (bootError) {
|
|
21605
|
-
return html4`<div class="notice err"
|
|
22702
|
+
return html4`<div class="notice err">${t4("common.loadingFailed", { name: "chat", error: bootError })}</div>`;
|
|
21606
22703
|
}
|
|
21607
22704
|
const autoScrollInFlight = F2(false);
|
|
21608
22705
|
_2(() => {
|
|
@@ -21664,10 +22761,10 @@ function ChatPanel() {
|
|
|
21664
22761
|
}
|
|
21665
22762
|
};
|
|
21666
22763
|
tick();
|
|
21667
|
-
const
|
|
22764
|
+
const t5 = setInterval(tick, 2500);
|
|
21668
22765
|
return () => {
|
|
21669
22766
|
cancelled = true;
|
|
21670
|
-
clearInterval(
|
|
22767
|
+
clearInterval(t5);
|
|
21671
22768
|
};
|
|
21672
22769
|
}, []);
|
|
21673
22770
|
const setEditMode = x2(async (next) => {
|
|
@@ -21702,25 +22799,25 @@ function ChatPanel() {
|
|
|
21702
22799
|
<div class="chat-shell">
|
|
21703
22800
|
<div style="display:flex;align-items:center;gap:12px;margin-bottom:10px">
|
|
21704
22801
|
<div class="chips" style="padding:0">
|
|
21705
|
-
<span class="chip-f active">${MODE === "attached" ? "
|
|
22802
|
+
<span class="chip-f active">${MODE === "attached" ? t4("chat.modeMirror") : t4("chat.modeView")}</span>
|
|
21706
22803
|
</div>
|
|
21707
22804
|
<div class="header-pickers" style="margin-left:auto">
|
|
21708
22805
|
${effort ? html4`
|
|
21709
|
-
<div class="mode-picker" title
|
|
22806
|
+
<div class="mode-picker" title=${t4("chat.effortTitle")}>
|
|
21710
22807
|
${["high", "max"].map(
|
|
21711
22808
|
(e3) => html4`
|
|
21712
22809
|
<button
|
|
21713
22810
|
key=${e3}
|
|
21714
22811
|
class="mode-btn ${effort === e3 ? "active accent" : ""}"
|
|
21715
22812
|
onClick=${() => setSetting("reasoningEffort", e3)}
|
|
21716
|
-
title=${e3 === "max" ? "
|
|
22813
|
+
title=${e3 === "max" ? t4("chat.effortMaxTitle") : t4("chat.effortHighTitle")}
|
|
21717
22814
|
>${e3}</button>
|
|
21718
22815
|
`
|
|
21719
22816
|
)}
|
|
21720
22817
|
</div>
|
|
21721
22818
|
` : null}
|
|
21722
22819
|
${preset ? html4`
|
|
21723
|
-
<div class="mode-picker" title
|
|
22820
|
+
<div class="mode-picker" title=${t4("chat.presetTitle")}>
|
|
21724
22821
|
${(() => {
|
|
21725
22822
|
const KNOWN = ["auto", "flash", "pro"];
|
|
21726
22823
|
const canonical = KNOWN.includes(preset) ? preset : "auto";
|
|
@@ -21730,7 +22827,7 @@ function ChatPanel() {
|
|
|
21730
22827
|
key=${p3}
|
|
21731
22828
|
class="mode-btn ${canonical === p3 ? "active accent" : ""}"
|
|
21732
22829
|
onClick=${() => setSetting("preset", p3)}
|
|
21733
|
-
title=${p3 === "auto" ? "
|
|
22830
|
+
title=${p3 === "auto" ? t4("chat.presetAutoTitle") : p3 === "flash" ? t4("chat.presetFlashTitle") : t4("chat.presetProTitle")}
|
|
21734
22831
|
>${p3}</button>
|
|
21735
22832
|
`
|
|
21736
22833
|
);
|
|
@@ -21738,14 +22835,14 @@ function ChatPanel() {
|
|
|
21738
22835
|
</div>
|
|
21739
22836
|
` : null}
|
|
21740
22837
|
${editMode ? html4`
|
|
21741
|
-
<div class="mode-picker" title
|
|
22838
|
+
<div class="mode-picker" title=${t4("chat.editGateTitle")}>
|
|
21742
22839
|
${["review", "auto", "yolo"].map(
|
|
21743
22840
|
(m2) => html4`
|
|
21744
22841
|
<button
|
|
21745
22842
|
key=${m2}
|
|
21746
22843
|
class="mode-btn ${editMode === m2 ? "active" : ""} ${m2 === "yolo" ? "yolo" : ""}"
|
|
21747
22844
|
onClick=${() => setEditMode(m2)}
|
|
21748
|
-
title=${m2 === "review" ? "
|
|
22845
|
+
title=${m2 === "review" ? t4("chat.editReviewTitle") : m2 === "auto" ? t4("chat.editAutoTitle") : t4("chat.editYoloTitle")}
|
|
21749
22846
|
>${m2}</button>
|
|
21750
22847
|
`
|
|
21751
22848
|
)}
|
|
@@ -21758,19 +22855,19 @@ function ChatPanel() {
|
|
|
21758
22855
|
${semanticIndex === false && !semanticBannerDismissed ? html4`<div class="chat-banner">
|
|
21759
22856
|
<span class="chat-banner-icon">≈</span>
|
|
21760
22857
|
<span class="chat-banner-text">
|
|
21761
|
-
<strong
|
|
22858
|
+
<strong>${t4("chat.semanticBanner")}</strong>
|
|
21762
22859
|
<span class="muted">
|
|
21763
|
-
|
|
22860
|
+
${t4("chat.semanticBannerDesc")}
|
|
21764
22861
|
</span>
|
|
21765
22862
|
</span>
|
|
21766
22863
|
<button
|
|
21767
22864
|
class="primary"
|
|
21768
22865
|
onClick=${() => appBus.dispatchEvent(new CustomEvent("navigate-tab", { detail: { tabId: "semantic" } }))}
|
|
21769
|
-
|
|
22866
|
+
>${t4("chat.semanticBannerBtn")}</button>
|
|
21770
22867
|
<button
|
|
21771
22868
|
class="chat-banner-close"
|
|
21772
22869
|
onClick=${() => setSemanticBannerDismissed(true)}
|
|
21773
|
-
title
|
|
22870
|
+
title=${t4("chat.semanticBannerDismiss")}
|
|
21774
22871
|
>×</button>
|
|
21775
22872
|
</div>` : null}
|
|
21776
22873
|
${error ? html4`<div class="notice err">${error}</div>` : null}
|
|
@@ -21781,7 +22878,7 @@ function ChatPanel() {
|
|
|
21781
22878
|
<div class="chat-main">
|
|
21782
22879
|
<div class="chat-feed" ref=${feedRef}>
|
|
21783
22880
|
${allMessages.length === 0 ? html4`<div class="chat-empty">
|
|
21784
|
-
|
|
22881
|
+
${t4("chat.noConversation")}
|
|
21785
22882
|
</div>` : allMessages.map(
|
|
21786
22883
|
(m2) => html4`
|
|
21787
22884
|
<${ChatMessage}
|
|
@@ -21796,7 +22893,7 @@ function ChatPanel() {
|
|
|
21796
22893
|
<div class="chat-input-area" style="position:relative">
|
|
21797
22894
|
${popoverKind && popoverItems.length > 0 ? html4`
|
|
21798
22895
|
<div class="popover" style="position:absolute;bottom:calc(100% + 6px);left:0;width:380px;max-height:280px;overflow-y:auto;z-index:10">
|
|
21799
|
-
<div class="popover-h">${popoverKind === "slash" ? "
|
|
22896
|
+
<div class="popover-h">${popoverKind === "slash" ? t4("chat.slashCommands") : t4("chat.projectFiles")}</div>
|
|
21800
22897
|
${popoverItems.map(
|
|
21801
22898
|
(it, i3) => html4`
|
|
21802
22899
|
<div
|
|
@@ -21816,7 +22913,7 @@ function ChatPanel() {
|
|
|
21816
22913
|
</div>
|
|
21817
22914
|
` : null}
|
|
21818
22915
|
<textarea
|
|
21819
|
-
placeholder=${busy ? "
|
|
22916
|
+
placeholder=${busy ? t4("chat.placeholderBusy") : t4("chat.placeholder")}
|
|
21820
22917
|
value=${input}
|
|
21821
22918
|
onInput=${onInput}
|
|
21822
22919
|
onKeyDown=${onKeyDown}
|
|
@@ -21829,10 +22926,10 @@ function ChatPanel() {
|
|
|
21829
22926
|
class="primary"
|
|
21830
22927
|
onClick=${send}
|
|
21831
22928
|
disabled=${busy || !input.trim()}
|
|
21832
|
-
|
|
22929
|
+
>${t4("chat.send")}</button>
|
|
21833
22930
|
<div style="display: flex; gap: 6px;">
|
|
21834
|
-
<button onClick=${newConversation} title
|
|
21835
|
-
<button onClick=${clearScrollback} title
|
|
22931
|
+
<button onClick=${newConversation} title=${t4("chat.newTitle")}>${t4("chat.new")}</button>
|
|
22932
|
+
<button onClick=${clearScrollback} title=${t4("chat.clearTitle")}>${t4("chat.clear")}</button>
|
|
21836
22933
|
</div>
|
|
21837
22934
|
</div>
|
|
21838
22935
|
</div>
|
|
@@ -21854,6 +22951,7 @@ function ChatPanel() {
|
|
|
21854
22951
|
`;
|
|
21855
22952
|
}
|
|
21856
22953
|
function SideRail({ stats, budgetUsd, activePlan }) {
|
|
22954
|
+
useLang();
|
|
21857
22955
|
if (!stats && !activePlan) return html4`<aside class="chat-rail"></aside>`;
|
|
21858
22956
|
const cachePct = stats ? Math.round(stats.cacheHitRatio * 100) : 0;
|
|
21859
22957
|
const cacheTone = cachePct >= 80 ? "ok" : cachePct >= 50 ? "" : "warn";
|
|
@@ -21865,12 +22963,12 @@ function SideRail({ stats, budgetUsd, activePlan }) {
|
|
|
21865
22963
|
${activePlan ? html4`<${ActivePlanCard} plan=${activePlan} />` : null}
|
|
21866
22964
|
${stats ? html4`
|
|
21867
22965
|
<div class="rail-card">
|
|
21868
|
-
<div class="rh"
|
|
21869
|
-
<div class="rail-kv"><span class="k"
|
|
21870
|
-
<div class="rail-kv"><span class="k"
|
|
21871
|
-
<div class="rail-kv"><span class="k"
|
|
22966
|
+
<div class="rh">${t4("chat.railSession")}</div>
|
|
22967
|
+
<div class="rail-kv"><span class="k">${t4("chat.railTurns")}</span><span class="v">${stats.turns.toLocaleString()}</span></div>
|
|
22968
|
+
<div class="rail-kv"><span class="k">${t4("chat.railPromptTok")}</span><span class="v">${stats.lastPromptTokens.toLocaleString()}</span></div>
|
|
22969
|
+
<div class="rail-kv"><span class="k">${t4("chat.railCost")}</span><span class="v">${fmtUsd(stats.totalCostUsd)}</span></div>
|
|
21872
22970
|
<div class="progress-row" style="margin-top:8px">
|
|
21873
|
-
<span class="lbl"
|
|
22971
|
+
<span class="lbl">${t4("chat.railCacheHit")}</span>
|
|
21874
22972
|
<div class=${`progress ${cacheTone}`}><div class="progress-fill" style=${`width:${cachePct}%`}></div></div>
|
|
21875
22973
|
<span class="v">${cachePct}%</span>
|
|
21876
22974
|
</div>
|
|
@@ -21878,9 +22976,9 @@ function SideRail({ stats, budgetUsd, activePlan }) {
|
|
|
21878
22976
|
` : null}
|
|
21879
22977
|
${showBudget ? html4`
|
|
21880
22978
|
<div class="rail-card">
|
|
21881
|
-
<div class="rh"
|
|
22979
|
+
<div class="rh">${t4("chat.railToolBudget")}</div>
|
|
21882
22980
|
<div class="progress-row">
|
|
21883
|
-
<span class="lbl"
|
|
22981
|
+
<span class="lbl">${t4("chat.railSpend")}</span>
|
|
21884
22982
|
<div class=${`progress ${budgetTone}`}><div class="progress-fill" style=${`width:${Math.min(100, budgetPct)}%`}></div></div>
|
|
21885
22983
|
<span class="v" style=${budgetTone === "err" ? "color:var(--c-err)" : budgetTone === "warn" ? "color:var(--c-warn)" : ""}>${fmtUsd(stats.totalCostUsd)} / ${fmtUsd(budgetUsd)}</span>
|
|
21886
22984
|
</div>
|
|
@@ -21890,6 +22988,7 @@ function SideRail({ stats, budgetUsd, activePlan }) {
|
|
|
21890
22988
|
`;
|
|
21891
22989
|
}
|
|
21892
22990
|
function ActivePlanCard({ plan }) {
|
|
22991
|
+
useLang();
|
|
21893
22992
|
const dots = [];
|
|
21894
22993
|
for (let i3 = 0; i3 < plan.totalSteps; i3++) {
|
|
21895
22994
|
const done = i3 < plan.completedSteps;
|
|
@@ -21903,10 +23002,10 @@ function ActivePlanCard({ plan }) {
|
|
|
21903
23002
|
}
|
|
21904
23003
|
return html4`
|
|
21905
23004
|
<div class="rail-card">
|
|
21906
|
-
<div class="rh"
|
|
23005
|
+
<div class="rh">${t4("chat.railActivePlan")}</div>
|
|
21907
23006
|
<div class="steps" style="margin-bottom:8px">${dots}</div>
|
|
21908
23007
|
<div class="rail-kv"><span class="k" style="font-family:var(--font-sans);color:var(--fg-1);font-size:12.5px">${plan.title}</span></div>
|
|
21909
|
-
<div class="rail-kv"><span class="k"
|
|
23008
|
+
<div class="rail-kv"><span class="k">${t4("chat.railProgress")}</span><span class="v">${plan.completedSteps} / ${plan.totalSteps}</span></div>
|
|
21910
23009
|
</div>
|
|
21911
23010
|
`;
|
|
21912
23011
|
}
|
|
@@ -21940,12 +23039,13 @@ function InFlightRow({
|
|
|
21940
23039
|
onAbort,
|
|
21941
23040
|
tick: _tick
|
|
21942
23041
|
}) {
|
|
23042
|
+
useLang();
|
|
21943
23043
|
const elapsedMs = startedAt ? Date.now() - startedAt : 0;
|
|
21944
23044
|
const elapsed = (elapsedMs / 1e3).toFixed(1);
|
|
21945
23045
|
const reasoningLen = streaming?.reasoning?.length ?? 0;
|
|
21946
23046
|
const textLen = streaming?.text?.length ?? 0;
|
|
21947
23047
|
const toolSummary = summarizeActiveTool(activeTool);
|
|
21948
|
-
const phase = toolSummary ? "
|
|
23048
|
+
const phase = toolSummary ? t4("chat.inflightRunning") : reasoningLen > 0 && textLen === 0 ? t4("chat.inflightThinking") : textLen > 0 ? t4("chat.inflightStreaming") : t4("chat.inflightWaiting");
|
|
21949
23049
|
return html4`
|
|
21950
23050
|
<div class="chat-inflight">
|
|
21951
23051
|
<span class="spinner"></span>
|
|
@@ -21959,24 +23059,25 @@ function InFlightRow({
|
|
|
21959
23059
|
${!toolSummary && (textLen > 0 || reasoningLen > 0) ? html4`
|
|
21960
23060
|
<span class="chat-inflight-sep">·</span>
|
|
21961
23061
|
<span class="muted">
|
|
21962
|
-
${reasoningLen > 0 ? html4
|
|
23062
|
+
${reasoningLen > 0 ? html4`${t4("chat.inflightReasoning", { count: reasoningLen.toLocaleString() })}` : null}
|
|
21963
23063
|
${reasoningLen > 0 && textLen > 0 ? html4`<span> · </span>` : null}
|
|
21964
|
-
${textLen > 0 ? html4
|
|
23064
|
+
${textLen > 0 ? html4`${t4("chat.inflightOut", { count: textLen.toLocaleString() })}` : null}
|
|
21965
23065
|
</span>
|
|
21966
23066
|
` : null}
|
|
21967
23067
|
${statusLine ? html4`
|
|
21968
23068
|
<span class="chat-inflight-sep">·</span>
|
|
21969
23069
|
<span class="muted">${statusLine}</span>
|
|
21970
23070
|
` : null}
|
|
21971
|
-
<button class="chat-inflight-abort" onClick=${onAbort}
|
|
23071
|
+
<button class="chat-inflight-abort" onClick=${onAbort}>${t4("chat.abortBtn")}</button>
|
|
21972
23072
|
</div>
|
|
21973
23073
|
`;
|
|
21974
23074
|
}
|
|
21975
23075
|
function ChatStatusBar({ stats, model }) {
|
|
23076
|
+
useLang();
|
|
21976
23077
|
if (!stats) {
|
|
21977
23078
|
return html4`
|
|
21978
23079
|
<div class="chat-statusbar">
|
|
21979
|
-
<span class="muted"
|
|
23080
|
+
<span class="muted">${t4("chat.waitingStats")}</span>
|
|
21980
23081
|
</div>
|
|
21981
23082
|
`;
|
|
21982
23083
|
}
|
|
@@ -21985,36 +23086,36 @@ function ChatStatusBar({ stats, model }) {
|
|
|
21985
23086
|
return html4`
|
|
21986
23087
|
<div class="chat-statusbar">
|
|
21987
23088
|
<span class="status-item">
|
|
21988
|
-
<span class="status-label"
|
|
23089
|
+
<span class="status-label">${t4("chat.statusModel")}</span>
|
|
21989
23090
|
<code>${model ?? "\u2014"}</code>
|
|
21990
23091
|
</span>
|
|
21991
23092
|
<span class="status-item">
|
|
21992
|
-
<span class="status-label"
|
|
23093
|
+
<span class="status-label">${t4("chat.statusCtx")}</span>
|
|
21993
23094
|
<span class="status-bar-mini">
|
|
21994
23095
|
<span class="status-bar-mini-fill" style=${`width: ${Math.min(100, ctxPct).toFixed(1)}%;`}></span>
|
|
21995
23096
|
</span>
|
|
21996
23097
|
<span class="muted">${stats.lastPromptTokens.toLocaleString()} / ${(stats.contextCapTokens / 1e3).toFixed(0)}K</span>
|
|
21997
23098
|
</span>
|
|
21998
23099
|
<span class="status-item">
|
|
21999
|
-
<span class="status-label"
|
|
23100
|
+
<span class="status-label">${t4("chat.statusCache")}</span>
|
|
22000
23101
|
<span class=${stats.cacheHitRatio >= 0.9 ? "status-ok" : stats.cacheHitRatio >= 0.6 ? "status-warn" : "status-err"}>
|
|
22001
23102
|
${(stats.cacheHitRatio * 100).toFixed(1)}%
|
|
22002
23103
|
</span>
|
|
22003
23104
|
</span>
|
|
22004
23105
|
<span class="status-item">
|
|
22005
|
-
<span class="status-label"
|
|
23106
|
+
<span class="status-label">${t4("chat.statusTurn")}</span>
|
|
22006
23107
|
<code>${fmtUsd(stats.lastTurnCostUsd)}</code>
|
|
22007
23108
|
</span>
|
|
22008
23109
|
<span class="status-item">
|
|
22009
|
-
<span class="status-label"
|
|
23110
|
+
<span class="status-label">${t4("chat.statusSession")}</span>
|
|
22010
23111
|
<code>${fmtUsd(stats.totalCostUsd)}</code>
|
|
22011
23112
|
<span class="muted" style="font-size: 10px;">
|
|
22012
|
-
|
|
23113
|
+
${t4("chat.statusTurns", { count: stats.turns, s: stats.turns === 1 ? "" : "s" })}
|
|
22013
23114
|
</span>
|
|
22014
23115
|
</span>
|
|
22015
23116
|
${balance ? html4`
|
|
22016
23117
|
<span class="status-item">
|
|
22017
|
-
<span class="status-label"
|
|
23118
|
+
<span class="status-label">${t4("chat.statusBalance")}</span>
|
|
22018
23119
|
<code>${balance.total_balance} ${balance.currency}</code>
|
|
22019
23120
|
</span>
|
|
22020
23121
|
` : null}
|
|
@@ -22043,6 +23144,7 @@ function buildMatrix(data) {
|
|
|
22043
23144
|
return [...rows.values()];
|
|
22044
23145
|
}
|
|
22045
23146
|
function HooksPanel() {
|
|
23147
|
+
useLang();
|
|
22046
23148
|
const [data, setData] = p2(null);
|
|
22047
23149
|
const [error, setError] = p2(null);
|
|
22048
23150
|
const [drafts, setDrafts] = p2({});
|
|
@@ -22078,7 +23180,7 @@ function HooksPanel() {
|
|
|
22078
23180
|
try {
|
|
22079
23181
|
await api("/hooks/save", { method: "POST", body: { scope, hooks: parsed } });
|
|
22080
23182
|
await api("/hooks/reload", { method: "POST", body: {} });
|
|
22081
|
-
setInfo(
|
|
23183
|
+
setInfo(t4("hooks.savedReloaded", { scope }));
|
|
22082
23184
|
setTimeout(() => setInfo(null), 3e3);
|
|
22083
23185
|
await load();
|
|
22084
23186
|
} catch (err) {
|
|
@@ -22090,7 +23192,7 @@ function HooksPanel() {
|
|
|
22090
23192
|
[drafts, load]
|
|
22091
23193
|
);
|
|
22092
23194
|
if (!data && !error)
|
|
22093
|
-
return html4`<div class="card" style="color:var(--fg-3)"
|
|
23195
|
+
return html4`<div class="card" style="color:var(--fg-3)">${t4("hooks.loading")}</div>`;
|
|
22094
23196
|
if (error && !data) return html4`<div class="card accent-err">${error}</div>`;
|
|
22095
23197
|
if (!data) return null;
|
|
22096
23198
|
const sectionH3 = (text, sub) => html4`
|
|
@@ -22104,20 +23206,19 @@ function HooksPanel() {
|
|
|
22104
23206
|
return html4`
|
|
22105
23207
|
<div style="display:flex;flex-direction:column;gap:6px">
|
|
22106
23208
|
<div class="chips">
|
|
22107
|
-
<span class="chip-f active"
|
|
23209
|
+
<span class="chip-f active">${t4("hooks.resolved")} <span class="ct">${data.resolved.length}</span></span>
|
|
22108
23210
|
${data.events.map((ev) => html4`<span class="chip-f">${ev}</span>`)}
|
|
22109
23211
|
</div>
|
|
22110
23212
|
${info ? html4`<div><span class="pill ok">${info}</span></div>` : null}
|
|
22111
23213
|
${error ? html4`<div class="card accent-err">${error}</div>` : null}
|
|
22112
23214
|
|
|
22113
|
-
${sectionH3("
|
|
22114
|
-
|
|
22115
|
-
No hooks configured. Edit the JSON below to add some.
|
|
23215
|
+
${sectionH3(t4("hooks.eventMatrix"), t4("hooks.matrixSub", { scripts: matrixRows.length, s: matrixRows.length === 1 ? "" : "s", events: events.length }))}${matrixRows.length === 0 ? html4`<div class="card" style="color:var(--fg-3)">
|
|
23216
|
+
${t4("hooks.noHooks")}
|
|
22116
23217
|
</div>` : html4`
|
|
22117
23218
|
<div class="card" style="padding:10px 14px;overflow-x:auto">
|
|
22118
23219
|
<div class="matrix" style=${`min-width:fit-content`}>
|
|
22119
23220
|
<div class="row h" style=${`grid-template-columns:${gridCols}`}>
|
|
22120
|
-
<div
|
|
23221
|
+
<div>${t4("hooks.colScript")}</div>
|
|
22121
23222
|
${events.map((ev) => html4`<div>${ev}</div>`)}
|
|
22122
23223
|
</div>
|
|
22123
23224
|
${matrixRows.map(
|
|
@@ -22148,8 +23249,7 @@ function HooksPanel() {
|
|
|
22148
23249
|
return html4`
|
|
22149
23250
|
${sectionH3(scope, meta.path ?? "(no path)")}
|
|
22150
23251
|
${scope === "project" && !meta.path ? html4`<div class="card" style="color:var(--fg-3)">
|
|
22151
|
-
|
|
22152
|
-
<code class="mono">reasonix code</code> to edit project hooks.
|
|
23252
|
+
${t4("hooks.noProject")}
|
|
22153
23253
|
</div>` : html4`
|
|
22154
23254
|
<div class="card">
|
|
22155
23255
|
<textarea
|
|
@@ -22160,27 +23260,27 @@ function HooksPanel() {
|
|
|
22160
23260
|
></textarea>
|
|
22161
23261
|
<div style="display:flex;gap:6px;margin-top:8px">
|
|
22162
23262
|
<button class="btn primary" disabled=${busy} onClick=${() => saveScope(scope)}>
|
|
22163
|
-
|
|
23263
|
+
${t4("hooks.saveReload")}
|
|
22164
23264
|
</button>
|
|
22165
|
-
<button class="btn ghost" disabled=${busy} onClick=${load}
|
|
23265
|
+
<button class="btn ghost" disabled=${busy} onClick=${load}>${t4("hooks.discard")}</button>
|
|
22166
23266
|
</div>
|
|
22167
23267
|
</div>
|
|
22168
23268
|
`}
|
|
22169
23269
|
`;
|
|
22170
23270
|
})}
|
|
22171
23271
|
|
|
22172
|
-
${sectionH3("
|
|
23272
|
+
${sectionH3(t4("hooks.recentRuns"), `${data.recentRuns?.length ?? 0}`)}
|
|
22173
23273
|
${!data.recentRuns || data.recentRuns.length === 0 ? html4`<div class="card" style="color:var(--fg-3)">
|
|
22174
|
-
|
|
23274
|
+
${t4("hooks.noRuns")}
|
|
22175
23275
|
</div>` : html4`
|
|
22176
23276
|
<div class="card" style="padding:0;overflow-x:auto">
|
|
22177
23277
|
<table class="tbl" style="width:100%;font-family:var(--font-mono);font-size:11.5px">
|
|
22178
23278
|
<thead>
|
|
22179
23279
|
<tr>
|
|
22180
|
-
<th style="text-align:left;padding:8px 12px"
|
|
22181
|
-
<th style="text-align:left;padding:8px 12px"
|
|
22182
|
-
<th style="text-align:left;padding:8px 12px"
|
|
22183
|
-
<th style="text-align:left;padding:8px 12px"
|
|
23280
|
+
<th style="text-align:left;padding:8px 12px">${t4("hooks.colWhen")}</th>
|
|
23281
|
+
<th style="text-align:left;padding:8px 12px">${t4("hooks.colPhase")}</th>
|
|
23282
|
+
<th style="text-align:left;padding:8px 12px">${t4("hooks.colHook")}</th>
|
|
23283
|
+
<th style="text-align:left;padding:8px 12px">${t4("hooks.colOutcome")}</th>
|
|
22184
23284
|
</tr>
|
|
22185
23285
|
</thead>
|
|
22186
23286
|
<tbody>
|
|
@@ -22214,6 +23314,7 @@ function specCommand(spec) {
|
|
|
22214
23314
|
return eq > 0 ? spec.slice(eq + 1) : spec;
|
|
22215
23315
|
}
|
|
22216
23316
|
function McpPanel() {
|
|
23317
|
+
useLang();
|
|
22217
23318
|
const [data, setData] = p2(null);
|
|
22218
23319
|
const [specs, setSpecs] = p2(null);
|
|
22219
23320
|
const [error, setError] = p2(null);
|
|
@@ -22243,7 +23344,7 @@ function McpPanel() {
|
|
|
22243
23344
|
body: { spec: newSpec.trim() }
|
|
22244
23345
|
});
|
|
22245
23346
|
setInfo(
|
|
22246
|
-
r3.requiresRestart ? "
|
|
23347
|
+
r3.requiresRestart ? t4("mcp.savedRestart") : t4("mcp.saved")
|
|
22247
23348
|
);
|
|
22248
23349
|
setTimeout(() => setInfo(null), 4e3);
|
|
22249
23350
|
setNewSpec("");
|
|
@@ -22256,13 +23357,11 @@ function McpPanel() {
|
|
|
22256
23357
|
}, [newSpec, load]);
|
|
22257
23358
|
const removeSpec = x2(
|
|
22258
23359
|
async (spec) => {
|
|
22259
|
-
if (!confirm(
|
|
22260
|
-
|
|
22261
|
-
${spec}`)) return;
|
|
23360
|
+
if (!confirm(t4("mcp.removeConfirm", { spec }))) return;
|
|
22262
23361
|
setBusy(true);
|
|
22263
23362
|
try {
|
|
22264
23363
|
await api("/mcp/specs", { method: "DELETE", body: { spec } });
|
|
22265
|
-
setInfo("removed
|
|
23364
|
+
setInfo(t4("mcp.removed"));
|
|
22266
23365
|
setTimeout(() => setInfo(null), 4e3);
|
|
22267
23366
|
await load();
|
|
22268
23367
|
} catch (err) {
|
|
@@ -22273,7 +23372,7 @@ ${spec}`)) return;
|
|
|
22273
23372
|
},
|
|
22274
23373
|
[load]
|
|
22275
23374
|
);
|
|
22276
|
-
if (!data && !error) return html4`<div class="card" style="color:var(--fg-3)"
|
|
23375
|
+
if (!data && !error) return html4`<div class="card" style="color:var(--fg-3)">${t4("mcp.loading")}</div>`;
|
|
22277
23376
|
if (error && !data) return html4`<div class="card accent-err">${error}</div>`;
|
|
22278
23377
|
if (!data) return null;
|
|
22279
23378
|
const liveCount = data.servers.length;
|
|
@@ -22285,19 +23384,19 @@ ${spec}`)) return;
|
|
|
22285
23384
|
<div class="sessions-grid">
|
|
22286
23385
|
<div class="sessions-list">
|
|
22287
23386
|
<div class="ssl-h" style="font-family:var(--font-mono);font-size:11px;color:var(--fg-3);text-transform:uppercase;letter-spacing:.1em">
|
|
22288
|
-
|
|
23387
|
+
${t4("mcp.servers", { count: liveCount })}
|
|
22289
23388
|
</div>
|
|
22290
23389
|
<div style="padding:8px 12px 4px">
|
|
22291
23390
|
<div class="chips">
|
|
22292
|
-
<span class=${`chip-f ${filter === "all" ? "active" : ""}`} onClick=${() => setFilter("all")}
|
|
22293
|
-
<span class=${`chip-f ${filter === "live" ? "active" : ""}`} onClick=${() => setFilter("live")}
|
|
22294
|
-
<span class=${`chip-f ${filter === "unbridged" ? "active" : ""}`} onClick=${() => setFilter("unbridged")}
|
|
23391
|
+
<span class=${`chip-f ${filter === "all" ? "active" : ""}`} onClick=${() => setFilter("all")}>${t4("mcp.all")} <span class="ct">${liveCount + unbridgedCount}</span></span>
|
|
23392
|
+
<span class=${`chip-f ${filter === "live" ? "active" : ""}`} onClick=${() => setFilter("live")}>${t4("mcp.live")} <span class="ct">${liveCount}</span></span>
|
|
23393
|
+
<span class=${`chip-f ${filter === "unbridged" ? "active" : ""}`} onClick=${() => setFilter("unbridged")}>${t4("mcp.unbridged")} <span class="ct">${unbridgedCount}</span></span>
|
|
22295
23394
|
</div>
|
|
22296
23395
|
</div>
|
|
22297
23396
|
<div style="padding:8px 12px;display:flex;gap:6px">
|
|
22298
23397
|
<input
|
|
22299
23398
|
type="text"
|
|
22300
|
-
placeholder
|
|
23399
|
+
placeholder=${t4("mcp.specPlaceholder")}
|
|
22301
23400
|
value=${newSpec}
|
|
22302
23401
|
onInput=${(e3) => setNewSpec(e3.target.value)}
|
|
22303
23402
|
style="flex:1;font-size:11px"
|
|
@@ -22309,7 +23408,7 @@ ${spec}`)) return;
|
|
|
22309
23408
|
|
|
22310
23409
|
<div class="ssl-rows">
|
|
22311
23410
|
${liveCount === 0 && unbridgedCount === 0 ? html4`<div style="color:var(--fg-3);padding:14px;font-size:12px">
|
|
22312
|
-
|
|
23411
|
+
${t4("mcp.noServers")}
|
|
22313
23412
|
</div>` : null}
|
|
22314
23413
|
${showLive ? data.servers.map(
|
|
22315
23414
|
(s3) => html4`
|
|
@@ -22320,9 +23419,9 @@ ${spec}`)) return;
|
|
|
22320
23419
|
setOpenUnbridged(null);
|
|
22321
23420
|
}}
|
|
22322
23421
|
>
|
|
22323
|
-
<span class="name">${s3.label} <span class="pill ok"
|
|
23422
|
+
<span class="name">${s3.label} <span class="pill ok">${t4("mcp.live")}</span></span>
|
|
22324
23423
|
<span class="preview">${specCommand(s3.spec)}</span>
|
|
22325
|
-
<span class="meta"><span><span class="v">${fmtNum(s3.toolCount)}</span> tools</span></span>
|
|
23424
|
+
<span class="meta"><span><span class="v">${fmtNum(s3.toolCount)}</span> ${t4("mcp.tools")}</span></span>
|
|
22326
23425
|
</div>
|
|
22327
23426
|
`
|
|
22328
23427
|
) : null}
|
|
@@ -22335,9 +23434,9 @@ ${spec}`)) return;
|
|
|
22335
23434
|
setOpen(null);
|
|
22336
23435
|
}}
|
|
22337
23436
|
>
|
|
22338
|
-
<span class="name">${specLabel(spec)} <span class="pill"
|
|
23437
|
+
<span class="name">${specLabel(spec)} <span class="pill">${t4("mcp.unbridged")}</span></span>
|
|
22339
23438
|
<span class="preview">${specCommand(spec)}</span>
|
|
22340
|
-
<span class="meta"><span class="dim"
|
|
23439
|
+
<span class="meta"><span class="dim">${t4("mcp.inConfig")}</span></span>
|
|
22341
23440
|
</div>
|
|
22342
23441
|
`
|
|
22343
23442
|
) : null}
|
|
@@ -22348,41 +23447,39 @@ ${spec}`)) return;
|
|
|
22348
23447
|
${openUnbridged != null ? html4`
|
|
22349
23448
|
<div class="sessions-detail-h">
|
|
22350
23449
|
<span class="name">${specLabel(openUnbridged)}</span>
|
|
22351
|
-
<span class="ws"><span class="pill"
|
|
23450
|
+
<span class="ws"><span class="pill">${t4("mcp.unbridgedTitle")}</span></span>
|
|
22352
23451
|
<span class="actions">
|
|
22353
23452
|
<button class="btn" disabled=${busy} onClick=${() => removeSpec(openUnbridged)}
|
|
22354
|
-
style="border-color:var(--c-err);color:var(--c-err)"
|
|
22355
|
-
<button class="btn ghost" onClick=${() => setOpenUnbridged(null)}
|
|
23453
|
+
style="border-color:var(--c-err);color:var(--c-err)">${t4("mcp.removeBtn")}</button>
|
|
23454
|
+
<button class="btn ghost" onClick=${() => setOpenUnbridged(null)}>${t4("common.back")}</button>
|
|
22356
23455
|
</span>
|
|
22357
23456
|
</div>
|
|
22358
23457
|
<div class="card" style="margin-bottom:12px">
|
|
22359
|
-
<div class="card-h"><span class="title"
|
|
23458
|
+
<div class="card-h"><span class="title">${t4("mcp.spec")}</span></div>
|
|
22360
23459
|
<code class="mono" style="font-size:11.5px;color:var(--fg-2);word-break:break-all">${openUnbridged}</code>
|
|
22361
23460
|
</div>
|
|
22362
23461
|
<div class="card accent-warn">
|
|
22363
|
-
<div class="card-h"><span class="title" style="color:var(--c-warn)"
|
|
23462
|
+
<div class="card-h"><span class="title" style="color:var(--c-warn)">${t4("mcp.whyUnbridged")}</span></div>
|
|
22364
23463
|
<div class="card-b" style="font-size:13px;line-height:1.6">
|
|
22365
|
-
|
|
22366
|
-
MCP servers attach when <code class="mono">reasonix code</code> starts; the dashboard alone can't
|
|
22367
|
-
spawn the child process.
|
|
23464
|
+
${t4("mcp.whyUnbridgedDesc")}
|
|
22368
23465
|
<div style="margin-top:10px;color:var(--fg-3);font-size:12px">
|
|
22369
|
-
|
|
23466
|
+
${t4("mcp.whyUnbridgedHint")}
|
|
22370
23467
|
</div>
|
|
22371
23468
|
</div>
|
|
22372
23469
|
</div>
|
|
22373
23470
|
` : open == null ? html4`<div style="color:var(--fg-3);font-size:13px;text-align:center;padding:60px 20px">
|
|
22374
|
-
|
|
23471
|
+
${t4("mcp.pickHint")}
|
|
22375
23472
|
</div>` : html4`
|
|
22376
23473
|
<div class="sessions-detail-h">
|
|
22377
23474
|
<span class="name">${open.label}</span>
|
|
22378
23475
|
<span class="ws">${open.serverInfo?.name ?? "\u2014"} ${open.serverInfo?.version ? `v${open.serverInfo.version}` : ""} · ${open.protocolVersion ?? "\u2014"}</span>
|
|
22379
23476
|
<span class="actions">
|
|
22380
|
-
<button class="btn ghost" onClick=${() => setOpen(null)}
|
|
23477
|
+
<button class="btn ghost" onClick=${() => setOpen(null)}>${t4("common.back")}</button>
|
|
22381
23478
|
</span>
|
|
22382
23479
|
</div>
|
|
22383
23480
|
|
|
22384
23481
|
<div class="card" style="margin-bottom:12px">
|
|
22385
|
-
<div class="card-h"><span class="title"
|
|
23482
|
+
<div class="card-h"><span class="title">${t4("mcp.spec")}</span></div>
|
|
22386
23483
|
<code class="mono" style="font-size:11.5px;color:var(--fg-2)">${open.spec}</code>
|
|
22387
23484
|
</div>
|
|
22388
23485
|
|
|
@@ -22391,14 +23488,14 @@ ${spec}`)) return;
|
|
|
22391
23488
|
</div>` : null}
|
|
22392
23489
|
|
|
22393
23490
|
<h3 style="margin:18px 0 6px;font-family:var(--font-mono);font-size:11px;color:var(--fg-3);text-transform:uppercase;letter-spacing:.1em">
|
|
22394
|
-
|
|
23491
|
+
${t4("mcp.toolsTitle", { count: open.tools.length })}
|
|
22395
23492
|
</h3>
|
|
22396
23493
|
<div class="card" style="padding:0;overflow:hidden">
|
|
22397
23494
|
<table class="tbl">
|
|
22398
|
-
<thead><tr><th
|
|
23495
|
+
<thead><tr><th>${t4("mcp.colName")}</th><th>${t4("mcp.colDesc")}</th></tr></thead>
|
|
22399
23496
|
<tbody>
|
|
22400
23497
|
${open.tools.map(
|
|
22401
|
-
(
|
|
23498
|
+
(tool) => html4`<tr><td><code class="mono">${tool.name}</code></td><td class="dim">${tool.description ?? ""}</td></tr>`
|
|
22402
23499
|
)}
|
|
22403
23500
|
</tbody>
|
|
22404
23501
|
</table>
|
|
@@ -22406,11 +23503,11 @@ ${spec}`)) return;
|
|
|
22406
23503
|
|
|
22407
23504
|
${open.resources.length > 0 ? html4`
|
|
22408
23505
|
<h3 style="margin:18px 0 6px;font-family:var(--font-mono);font-size:11px;color:var(--fg-3);text-transform:uppercase;letter-spacing:.1em">
|
|
22409
|
-
|
|
23506
|
+
${t4("mcp.resourcesTitle", { count: open.resources.length })}
|
|
22410
23507
|
</h3>
|
|
22411
23508
|
<div class="card" style="padding:0;overflow:hidden">
|
|
22412
23509
|
<table class="tbl">
|
|
22413
|
-
<thead><tr><th
|
|
23510
|
+
<thead><tr><th>${t4("mcp.colName")}</th><th>${t4("mcp.colUri")}</th></tr></thead>
|
|
22414
23511
|
<tbody>
|
|
22415
23512
|
${open.resources.map(
|
|
22416
23513
|
(r3) => html4`<tr><td>${r3.name}</td><td class="path">${r3.uri}</td></tr>`
|
|
@@ -22422,11 +23519,11 @@ ${spec}`)) return;
|
|
|
22422
23519
|
|
|
22423
23520
|
${open.prompts.length > 0 ? html4`
|
|
22424
23521
|
<h3 style="margin:18px 0 6px;font-family:var(--font-mono);font-size:11px;color:var(--fg-3);text-transform:uppercase;letter-spacing:.1em">
|
|
22425
|
-
|
|
23522
|
+
${t4("mcp.promptsTitle", { count: open.prompts.length })}
|
|
22426
23523
|
</h3>
|
|
22427
23524
|
<div class="card" style="padding:0;overflow:hidden">
|
|
22428
23525
|
<table class="tbl">
|
|
22429
|
-
<thead><tr><th
|
|
23526
|
+
<thead><tr><th>${t4("mcp.colName")}</th><th>${t4("mcp.colDesc")}</th></tr></thead>
|
|
22430
23527
|
<tbody>
|
|
22431
23528
|
${open.prompts.map(
|
|
22432
23529
|
(p3) => html4`<tr><td><code class="mono">${p3.name}</code></td><td class="dim">${p3.description ?? ""}</td></tr>`
|
|
@@ -22443,6 +23540,7 @@ ${spec}`)) return;
|
|
|
22443
23540
|
|
|
22444
23541
|
// dashboard/src/panels/memory.ts
|
|
22445
23542
|
function MemoryPanel() {
|
|
23543
|
+
useLang();
|
|
22446
23544
|
const [tree, setTree] = p2(null);
|
|
22447
23545
|
const [error, setError] = p2(null);
|
|
22448
23546
|
const [open, setOpen] = p2(null);
|
|
@@ -22479,7 +23577,7 @@ function MemoryPanel() {
|
|
|
22479
23577
|
try {
|
|
22480
23578
|
const path = open.scope === "project" ? "/memory/project" : `/memory/${open.scope}/${encodeURIComponent(open.name ?? "")}`;
|
|
22481
23579
|
await api(path, { method: "POST", body: { body } });
|
|
22482
|
-
setInfo(
|
|
23580
|
+
setInfo(t4("memory.saved", { scope: open.scope + (open.name ? `/${open.name}` : "") }));
|
|
22483
23581
|
setTimeout(() => setInfo(null), 3e3);
|
|
22484
23582
|
await load();
|
|
22485
23583
|
} catch (err) {
|
|
@@ -22489,7 +23587,7 @@ function MemoryPanel() {
|
|
|
22489
23587
|
}
|
|
22490
23588
|
}, [open, body, load]);
|
|
22491
23589
|
if (!tree && !error)
|
|
22492
|
-
return html4`<div class="card" style="color:var(--fg-3)"
|
|
23590
|
+
return html4`<div class="card" style="color:var(--fg-3)">${t4("memory.loading")}</div>`;
|
|
22493
23591
|
if (error && !tree) return html4`<div class="card accent-err">${error}</div>`;
|
|
22494
23592
|
if (!tree) return null;
|
|
22495
23593
|
const fileRow = (scope, f3) => {
|
|
@@ -22508,11 +23606,12 @@ function MemoryPanel() {
|
|
|
22508
23606
|
</div>
|
|
22509
23607
|
`;
|
|
22510
23608
|
};
|
|
23609
|
+
const totalFiles = (tree.project.path ? 1 : 0) + tree.global.files.length + tree.projectMem.files.length;
|
|
22511
23610
|
return html4`
|
|
22512
23611
|
<div class="sessions-grid">
|
|
22513
23612
|
<div class="sessions-list">
|
|
22514
23613
|
<div class="ssl-h" style="font-family:var(--font-mono);font-size:11px;color:var(--fg-3);text-transform:uppercase;letter-spacing:.1em">
|
|
22515
|
-
|
|
23614
|
+
${t4("memory.files", { count: totalFiles })}
|
|
22516
23615
|
</div>
|
|
22517
23616
|
<div class="ssl-rows">
|
|
22518
23617
|
${tree.project.path ? html4`
|
|
@@ -22522,7 +23621,7 @@ function MemoryPanel() {
|
|
|
22522
23621
|
>
|
|
22523
23622
|
<span class="name">
|
|
22524
23623
|
REASONIX.md
|
|
22525
|
-
${tree.project.exists ? html4`<span class="pill ok"
|
|
23624
|
+
${tree.project.exists ? html4`<span class="pill ok">${t4("memory.exists")}</span>` : html4`<span class="pill">${t4("memory.create")}</span>`}
|
|
22526
23625
|
</span>
|
|
22527
23626
|
<span class="preview">${tree.project.path}</span>
|
|
22528
23627
|
<span class="meta"><span class="dim">project</span></span>
|
|
@@ -22531,27 +23630,26 @@ function MemoryPanel() {
|
|
|
22531
23630
|
${tree.global.files.map((f3) => fileRow("global", f3))}
|
|
22532
23631
|
${tree.projectMem.files.map((f3) => fileRow("project-mem", f3))}
|
|
22533
23632
|
${tree.global.files.length === 0 && tree.projectMem.files.length === 0 && !tree.project.path ? html4`<div style="color:var(--fg-3);padding:14px;font-size:12px">
|
|
22534
|
-
|
|
23633
|
+
${t4("memory.noFiles")}
|
|
22535
23634
|
</div>` : null}
|
|
22536
23635
|
</div>
|
|
22537
23636
|
</div>
|
|
22538
23637
|
|
|
22539
23638
|
<div class="sessions-detail">
|
|
22540
23639
|
${open == null ? html4`<div style="color:var(--fg-3);font-size:13px;text-align:center;padding:60px 20px">
|
|
22541
|
-
|
|
23640
|
+
${t4("memory.pickHint")}
|
|
22542
23641
|
<div style="margin-top:12px;font-size:11.5px">
|
|
22543
|
-
|
|
22544
|
-
<code class="mono">~/.reasonix/memory/</code>.
|
|
23642
|
+
${t4("memory.pickDesc")}
|
|
22545
23643
|
</div>
|
|
22546
23644
|
</div>` : html4`
|
|
22547
23645
|
<div class="sessions-detail-h">
|
|
22548
23646
|
<span class="name">
|
|
22549
23647
|
${open.scope}${open.name ? `/${open.name}` : ""}
|
|
22550
23648
|
</span>
|
|
22551
|
-
<span class="ws">${body.length.toLocaleString()}
|
|
23649
|
+
<span class="ws">${t4("memory.chars", { count: body.length.toLocaleString() })}</span>
|
|
22552
23650
|
<span class="actions">
|
|
22553
|
-
<button class="btn primary" disabled=${busy} onClick=${save}
|
|
22554
|
-
<button class="btn ghost" onClick=${() => setOpen(null)}
|
|
23651
|
+
<button class="btn primary" disabled=${busy} onClick=${save}>${t4("common.save")}</button>
|
|
23652
|
+
<button class="btn ghost" onClick=${() => setOpen(null)}>${t4("common.back")}</button>
|
|
22555
23653
|
</span>
|
|
22556
23654
|
</div>
|
|
22557
23655
|
${info ? html4`<div style="margin-bottom:8px"><span class="pill ok">${info}</span></div>` : null}
|
|
@@ -22563,7 +23661,7 @@ function MemoryPanel() {
|
|
|
22563
23661
|
disabled=${busy}
|
|
22564
23662
|
></textarea>
|
|
22565
23663
|
<div style="margin-top:8px;color:var(--fg-3);font-size:11.5px">
|
|
22566
|
-
|
|
23664
|
+
${t4("memory.reloadHint")}
|
|
22567
23665
|
</div>
|
|
22568
23666
|
`}
|
|
22569
23667
|
</div>
|
|
@@ -22617,59 +23715,59 @@ function kpi(label, value, delta, deltaTone) {
|
|
|
22617
23715
|
`;
|
|
22618
23716
|
}
|
|
22619
23717
|
function deltaPctText(deltaPct) {
|
|
22620
|
-
if (deltaPct === null) return { text: "
|
|
22621
|
-
if (Math.abs(deltaPct) < 1) return { text: "
|
|
23718
|
+
if (deltaPct === null) return { text: t4("overview.noPriorData"), tone: "flat" };
|
|
23719
|
+
if (Math.abs(deltaPct) < 1) return { text: t4("overview.stable"), tone: "flat" };
|
|
22622
23720
|
const arrow = deltaPct > 0 ? "\u25B2" : "\u25BC";
|
|
22623
23721
|
return {
|
|
22624
|
-
text:
|
|
23722
|
+
text: t4("overview.vsPrior", { arrow, pct: Math.abs(deltaPct).toFixed(0) }),
|
|
22625
23723
|
tone: deltaPct > 0 ? "up" : "down"
|
|
22626
23724
|
};
|
|
22627
23725
|
}
|
|
22628
23726
|
function deltaPpText(deltaPp) {
|
|
22629
|
-
if (deltaPp === null) return { text: "
|
|
22630
|
-
if (Math.abs(deltaPp) < 0.5) return { text: "
|
|
23727
|
+
if (deltaPp === null) return { text: t4("overview.noPriorData"), tone: "flat" };
|
|
23728
|
+
if (Math.abs(deltaPp) < 0.5) return { text: t4("overview.stable"), tone: "flat" };
|
|
22631
23729
|
const arrow = deltaPp > 0 ? "\u25B2" : "\u25BC";
|
|
22632
23730
|
return { text: `${arrow} ${Math.abs(deltaPp).toFixed(1)}pp`, tone: deltaPp > 0 ? "up" : "down" };
|
|
22633
23731
|
}
|
|
22634
23732
|
function deltaCountText(delta) {
|
|
22635
|
-
if (delta === null || delta === 0) return { text: "
|
|
23733
|
+
if (delta === null || delta === 0) return { text: t4("overview.stable"), tone: "flat" };
|
|
22636
23734
|
const arrow = delta > 0 ? "\u25B2" : "\u25BC";
|
|
22637
23735
|
return { text: `${arrow} ${Math.abs(delta)}`, tone: delta > 0 ? "up" : "down" };
|
|
22638
23736
|
}
|
|
22639
23737
|
function balanceKpi(c3) {
|
|
22640
|
-
if (!c3.balance) return kpi("balance", "\u2014", "open in TUI", "flat");
|
|
23738
|
+
if (!c3.balance) return kpi(t4("overview.balance"), "\u2014", "open in TUI", "flat");
|
|
22641
23739
|
const symbol = c3.balance.currency === "CNY" ? "\xA5" : c3.balance.currency === "USD" ? "$" : "";
|
|
22642
|
-
return kpi("balance", `${symbol}${c3.balance.total}`, c3.balance.currency, "flat");
|
|
23740
|
+
return kpi(t4("overview.balance"), `${symbol}${c3.balance.total}`, c3.balance.currency, "flat");
|
|
22643
23741
|
}
|
|
22644
23742
|
function tokens7dKpi(c3) {
|
|
22645
|
-
if (!c3.tokens7d) return kpi("
|
|
23743
|
+
if (!c3.tokens7d) return kpi(t4("overview.tokens7d"), "\u2014", t4("overview.noUsageYet"), "flat");
|
|
22646
23744
|
const d3 = deltaPctText(c3.tokens7d.deltaPct);
|
|
22647
|
-
return kpi("
|
|
23745
|
+
return kpi(t4("overview.tokens7d"), fmtCompactNum(c3.tokens7d.total), d3.text, d3.tone);
|
|
22648
23746
|
}
|
|
22649
23747
|
function cacheHitKpi(c3) {
|
|
22650
|
-
if (!c3.cacheHit7d) return kpi("
|
|
23748
|
+
if (!c3.cacheHit7d) return kpi(t4("overview.cacheHit"), "\u2014", t4("overview.noUsageYet"), "flat");
|
|
22651
23749
|
const pct = (c3.cacheHit7d.ratio * 100).toFixed(0);
|
|
22652
23750
|
const d3 = deltaPpText(c3.cacheHit7d.deltaPp);
|
|
22653
23751
|
return html4`
|
|
22654
23752
|
<div class="kpi cock-w-1">
|
|
22655
|
-
<div class="label"
|
|
23753
|
+
<div class="label">${t4("overview.cacheHit")}</div>
|
|
22656
23754
|
<div class="value">${pct}<span class="unit">%</span></div>
|
|
22657
23755
|
<div class=${`delta ${d3.tone}`}>${d3.text}</div>
|
|
22658
23756
|
</div>
|
|
22659
23757
|
`;
|
|
22660
23758
|
}
|
|
22661
23759
|
function toolCallsKpi(c3) {
|
|
22662
|
-
if (!c3.toolCalls24h) return kpi("
|
|
23760
|
+
if (!c3.toolCalls24h) return kpi(t4("overview.toolCalls24h"), "\u2014", t4("overview.noToolCalls"), "flat");
|
|
22663
23761
|
const d3 = deltaCountText(c3.toolCalls24h.delta);
|
|
22664
|
-
return kpi("
|
|
23762
|
+
return kpi(t4("overview.toolCalls24h"), fmtNum(c3.toolCalls24h.total), d3.text, d3.tone);
|
|
22665
23763
|
}
|
|
22666
23764
|
function currentSessionBlock(c3) {
|
|
22667
23765
|
if (!c3.currentSession) {
|
|
22668
23766
|
return html4`
|
|
22669
23767
|
<div class="cock-list cock-w-2">
|
|
22670
|
-
<div class="ch"><span class="ttl"
|
|
23768
|
+
<div class="ch"><span class="ttl">${t4("overview.currentSession")}</span></div>
|
|
22671
23769
|
<div style="color:var(--fg-3);font-size:12.5px;padding:8px 0">
|
|
22672
|
-
|
|
23770
|
+
${t4("overview.noSession")}
|
|
22673
23771
|
</div>
|
|
22674
23772
|
</div>
|
|
22675
23773
|
`;
|
|
@@ -22677,14 +23775,14 @@ function currentSessionBlock(c3) {
|
|
|
22677
23775
|
const s3 = c3.currentSession;
|
|
22678
23776
|
return html4`
|
|
22679
23777
|
<div class="cock-list cock-w-2">
|
|
22680
|
-
<div class="ch"><span class="ttl"
|
|
23778
|
+
<div class="ch"><span class="ttl">${t4("overview.currentSession")}</span></div>
|
|
22681
23779
|
<div class="card accent-brand" style="margin:0 0 8px;background:transparent;border:none;padding:0">
|
|
22682
23780
|
<div class="card-h"><span class="glyph">◆</span><span class="title">${s3.id}</span><span class="meta">${s3.turns} turn${s3.turns === 1 ? "" : "s"}</span></div>
|
|
22683
23781
|
</div>
|
|
22684
23782
|
<div style="display:grid;grid-template-columns:repeat(3, 1fr);gap:8px;font-family:var(--font-mono);font-size:11px">
|
|
22685
|
-
<div><span style="color:var(--fg-3)"
|
|
22686
|
-
<div><span style="color:var(--fg-3)"
|
|
22687
|
-
<div><span style="color:var(--fg-3)"
|
|
23783
|
+
<div><span style="color:var(--fg-3)">${t4("overview.promptTok")}</span><div style="color:var(--fg-0);font-size:13px;font-weight:600">${fmtNum(s3.lastPromptTokens)}</div></div>
|
|
23784
|
+
<div><span style="color:var(--fg-3)">${t4("overview.completionTok")}</span><div style="color:var(--fg-0);font-size:13px;font-weight:600">${fmtNum(s3.completionTokens)}</div></div>
|
|
23785
|
+
<div><span style="color:var(--fg-3)">${t4("overview.cost")}</span><div style="color:var(--fg-0);font-size:13px;font-weight:600">${fmtUsd(s3.totalCostUsd)}</div></div>
|
|
22688
23786
|
</div>
|
|
22689
23787
|
</div>
|
|
22690
23788
|
`;
|
|
@@ -22693,8 +23791,8 @@ function costTrendSpark(c3) {
|
|
|
22693
23791
|
if (!c3.costTrend14d || c3.costTrend14d.length === 0) {
|
|
22694
23792
|
return html4`
|
|
22695
23793
|
<div class="chart cock-w-2">
|
|
22696
|
-
<div class="chart-h"><span class="title"
|
|
22697
|
-
<div class="chart-v" style="color:var(--fg-4)">—<span class="unit"
|
|
23794
|
+
<div class="chart-h"><span class="title">${t4("overview.costTrend")}</span></div>
|
|
23795
|
+
<div class="chart-v" style="color:var(--fg-4)">—<span class="unit">${t4("overview.noUsageYet")}</span></div>
|
|
22698
23796
|
</div>
|
|
22699
23797
|
`;
|
|
22700
23798
|
}
|
|
@@ -22712,8 +23810,8 @@ function costTrendSpark(c3) {
|
|
|
22712
23810
|
const avg = total / days2.length;
|
|
22713
23811
|
return html4`
|
|
22714
23812
|
<div class="chart cock-w-2">
|
|
22715
|
-
<div class="chart-h"><span class="title"
|
|
22716
|
-
<div class="chart-v">${fmtUsd(avg)}<span class="unit"
|
|
23813
|
+
<div class="chart-h"><span class="title">${t4("overview.costTrend")}</span></div>
|
|
23814
|
+
<div class="chart-v">${fmtUsd(avg)}<span class="unit">${t4("overview.dayAvg")}</span></div>
|
|
22717
23815
|
<div class="chart-spark">
|
|
22718
23816
|
<svg viewBox=${`0 0 ${w3} ${h3}`} preserveAspectRatio="none">
|
|
22719
23817
|
<polyline fill="none" stroke="var(--c-brand)" stroke-width="1.5" points=${points2} />
|
|
@@ -22726,8 +23824,8 @@ function costTrendSpark(c3) {
|
|
|
22726
23824
|
function recentPlansRail(c3) {
|
|
22727
23825
|
return html4`
|
|
22728
23826
|
<div class="cock-list cock-w-2">
|
|
22729
|
-
<div class="ch"><span class="ttl"
|
|
22730
|
-
${!c3.recentPlans || c3.recentPlans.length === 0 ? html4`<div style="color:var(--fg-3);font-size:12.5px;padding:8px 0"
|
|
23827
|
+
<div class="ch"><span class="ttl">${t4("overview.recentPlans")}</span></div>
|
|
23828
|
+
${!c3.recentPlans || c3.recentPlans.length === 0 ? html4`<div style="color:var(--fg-3);font-size:12.5px;padding:8px 0">${t4("overview.noPlans")}</div>` : c3.recentPlans.map(
|
|
22731
23829
|
(p3) => html4`
|
|
22732
23830
|
<div class=${`rail-step ${p3.status === "done" ? "done" : "active"}`}>
|
|
22733
23831
|
<span class="g">${p3.status === "done" ? "\u2713" : "\u23F5"}</span>
|
|
@@ -22742,8 +23840,8 @@ function recentPlansRail(c3) {
|
|
|
22742
23840
|
function toolActivityFeed(c3) {
|
|
22743
23841
|
return html4`
|
|
22744
23842
|
<div class="cock-list cock-w-2">
|
|
22745
|
-
<div class="ch"><span class="ttl"
|
|
22746
|
-
${!c3.toolActivity || c3.toolActivity.length === 0 ? html4`<div style="color:var(--fg-3);font-size:12.5px;padding:8px 0"
|
|
23843
|
+
<div class="ch"><span class="ttl">${t4("overview.toolActivity")}</span></div>
|
|
23844
|
+
${!c3.toolActivity || c3.toolActivity.length === 0 ? html4`<div style="color:var(--fg-3);font-size:12.5px;padding:8px 0">${t4("overview.noToolCalls")}</div>` : c3.toolActivity.map(
|
|
22747
23845
|
(r3) => html4`
|
|
22748
23846
|
<div class=${`feed-row ${r3.level}`}>
|
|
22749
23847
|
<span class="g">${r3.level === "ok" ? "\u25CF" : r3.level === "warn" ? "\u25B2" : "\u2715"}</span>
|
|
@@ -22756,10 +23854,11 @@ function toolActivityFeed(c3) {
|
|
|
22756
23854
|
`;
|
|
22757
23855
|
}
|
|
22758
23856
|
function OverviewPanel() {
|
|
23857
|
+
useLang();
|
|
22759
23858
|
const { data, error, loading } = usePoll("/overview", 2500);
|
|
22760
23859
|
if (loading && !data)
|
|
22761
|
-
return html4`<div class="card" style="color:var(--fg-3)"
|
|
22762
|
-
if (error) return html4`<div class="card accent-err"
|
|
23860
|
+
return html4`<div class="card" style="color:var(--fg-3)">${t4("overview.loading")}</div>`;
|
|
23861
|
+
if (error) return html4`<div class="card accent-err">${t4("overview.failed", { error: error.message })}</div>`;
|
|
22763
23862
|
if (!data) return null;
|
|
22764
23863
|
const o3 = data;
|
|
22765
23864
|
const c3 = o3.cockpit ?? {
|
|
@@ -22773,22 +23872,21 @@ function OverviewPanel() {
|
|
|
22773
23872
|
toolActivity: null
|
|
22774
23873
|
};
|
|
22775
23874
|
const upToDate = o3.latestVersion ? o3.latestVersion === o3.version : null;
|
|
22776
|
-
const versionDelta = upToDate === null ? "checking" : upToDate ? "latest" : `latest: ${o3.latestVersion}`;
|
|
23875
|
+
const versionDelta = upToDate === null ? t4("overview.checking") : upToDate ? t4("overview.latest") : `latest: ${o3.latestVersion}`;
|
|
22777
23876
|
const versionTone = upToDate === false ? "down" : "flat";
|
|
22778
23877
|
return html4`
|
|
22779
23878
|
<div style="display:flex;flex-direction:column;gap:14px">
|
|
22780
23879
|
${o3.mode === "standalone" ? html4`<div class="card accent-warn">
|
|
22781
23880
|
<div class="card-h">
|
|
22782
|
-
<span class="title" style="color:var(--c-warn)"
|
|
23881
|
+
<span class="title" style="color:var(--c-warn)">${t4("overview.standaloneTitle")}</span>
|
|
22783
23882
|
</div>
|
|
22784
23883
|
<div class="card-b">
|
|
22785
|
-
|
|
22786
|
-
<code class="mono">reasonix code</code> for live session state, MCP, and tools.
|
|
23884
|
+
${t4("overview.standaloneDesc")}
|
|
22787
23885
|
</div>
|
|
22788
23886
|
</div>` : null}
|
|
22789
23887
|
|
|
22790
23888
|
<h3 style="margin:0;font-family:var(--font-mono);font-size:11px;color:var(--fg-3);text-transform:uppercase;letter-spacing:.1em">
|
|
22791
|
-
|
|
23889
|
+
${t4("overview.cockpit")}
|
|
22792
23890
|
</h3>
|
|
22793
23891
|
<div class="cockpit">
|
|
22794
23892
|
${balanceKpi(c3)}
|
|
@@ -22802,17 +23900,17 @@ function OverviewPanel() {
|
|
|
22802
23900
|
${recentPlansRail(c3)}
|
|
22803
23901
|
${toolActivityFeed(c3)}
|
|
22804
23902
|
|
|
22805
|
-
${kpi("
|
|
22806
|
-
${kpi("
|
|
22807
|
-
${kpi("
|
|
22808
|
-
${kpi("
|
|
23903
|
+
${kpi(t4("overview.toolsLoaded"), fmtNum(o3.toolCount), o3.toolCount ? t4("overview.active") : "\u2014", "flat")}
|
|
23904
|
+
${kpi(t4("overview.mcpServers"), fmtNum(o3.mcpServerCount), o3.mcpServerCount ? t4("overview.allUp") : "\u2014", o3.mcpServerCount ? "up" : "flat")}
|
|
23905
|
+
${kpi(t4("overview.editMode"), o3.editMode ?? "\u2014", o3.editMode === "yolo" ? t4("overview.yoloWarning") : null, o3.editMode === "yolo" ? "down" : "flat")}
|
|
23906
|
+
${kpi(t4("overview.version"), o3.version ?? "\u2014", versionDelta, versionTone)}
|
|
22809
23907
|
</div>
|
|
22810
23908
|
|
|
22811
23909
|
<h3 style="margin:0;font-family:var(--font-mono);font-size:11px;color:var(--fg-3);text-transform:uppercase;letter-spacing:.1em">
|
|
22812
|
-
|
|
23910
|
+
${t4("overview.workingDir")}
|
|
22813
23911
|
</h3>
|
|
22814
23912
|
<div class="card">
|
|
22815
|
-
<div class="card-h"><span class="title"
|
|
23913
|
+
<div class="card-h"><span class="title">${t4("overview.projectRoot")}</span></div>
|
|
22816
23914
|
<code class="mono" style="color:var(--fg-2);font-size:12px">${o3.cwd ?? "\u2014"}</code>
|
|
22817
23915
|
</div>
|
|
22818
23916
|
</div>
|
|
@@ -22833,6 +23931,7 @@ function groupByVerb(list2) {
|
|
|
22833
23931
|
return [...groups.entries()];
|
|
22834
23932
|
}
|
|
22835
23933
|
function PermissionsPanel() {
|
|
23934
|
+
useLang();
|
|
22836
23935
|
const { data, error, loading, refresh } = usePoll("/permissions", 5e3);
|
|
22837
23936
|
const [draft, setDraft] = p2("");
|
|
22838
23937
|
const [busy, setBusy] = p2(false);
|
|
@@ -22847,8 +23946,8 @@ function PermissionsPanel() {
|
|
|
22847
23946
|
method: "POST",
|
|
22848
23947
|
body: { prefix }
|
|
22849
23948
|
});
|
|
22850
|
-
if (res.alreadyPresent) setFeedback({ kind: "info", text:
|
|
22851
|
-
else setFeedback({ kind: "ok", text:
|
|
23949
|
+
if (res.alreadyPresent) setFeedback({ kind: "info", text: t4("permissions.alreadyIn", { prefix }) });
|
|
23950
|
+
else setFeedback({ kind: "ok", text: t4("permissions.added", { prefix }) });
|
|
22852
23951
|
setDraft("");
|
|
22853
23952
|
await refresh();
|
|
22854
23953
|
} catch (err) {
|
|
@@ -22859,12 +23958,12 @@ function PermissionsPanel() {
|
|
|
22859
23958
|
}, [draft, refresh]);
|
|
22860
23959
|
const remove = x2(
|
|
22861
23960
|
async (prefix) => {
|
|
22862
|
-
if (!confirm(
|
|
23961
|
+
if (!confirm(t4("permissions.removeConfirm", { prefix }))) return;
|
|
22863
23962
|
setBusy(true);
|
|
22864
23963
|
setFeedback(null);
|
|
22865
23964
|
try {
|
|
22866
23965
|
await api("/permissions", { method: "DELETE", body: { prefix } });
|
|
22867
|
-
setFeedback({ kind: "ok", text:
|
|
23966
|
+
setFeedback({ kind: "ok", text: t4("permissions.removed", { prefix }) });
|
|
22868
23967
|
await refresh();
|
|
22869
23968
|
} catch (err) {
|
|
22870
23969
|
setFeedback({ kind: "err", text: err.message });
|
|
@@ -22875,7 +23974,7 @@ function PermissionsPanel() {
|
|
|
22875
23974
|
[refresh]
|
|
22876
23975
|
);
|
|
22877
23976
|
const clearAll = x2(async () => {
|
|
22878
|
-
if (!confirm("
|
|
23977
|
+
if (!confirm(t4("permissions.clearConfirm"))) return;
|
|
22879
23978
|
setBusy(true);
|
|
22880
23979
|
setFeedback(null);
|
|
22881
23980
|
try {
|
|
@@ -22885,7 +23984,7 @@ function PermissionsPanel() {
|
|
|
22885
23984
|
});
|
|
22886
23985
|
setFeedback({
|
|
22887
23986
|
kind: "ok",
|
|
22888
|
-
text:
|
|
23987
|
+
text: t4("permissions.cleared", { count: res.dropped, y: res.dropped === 1 ? "y" : "ies" })
|
|
22889
23988
|
});
|
|
22890
23989
|
await refresh();
|
|
22891
23990
|
} catch (err) {
|
|
@@ -22895,8 +23994,8 @@ function PermissionsPanel() {
|
|
|
22895
23994
|
}
|
|
22896
23995
|
}, [refresh]);
|
|
22897
23996
|
if (loading && !data)
|
|
22898
|
-
return html4`<div class="card" style="color:var(--fg-3)"
|
|
22899
|
-
if (error) return html4`<div class="card accent-err"
|
|
23997
|
+
return html4`<div class="card" style="color:var(--fg-3)">${t4("permissions.loading")}</div>`;
|
|
23998
|
+
if (error) return html4`<div class="card accent-err">${t4("common.loadingFailed", { name: "permissions", error: error.message })}</div>`;
|
|
22900
23999
|
if (!data) return null;
|
|
22901
24000
|
const p3 = data;
|
|
22902
24001
|
const feedbackPill = feedback ? html4`<span
|
|
@@ -22905,28 +24004,27 @@ function PermissionsPanel() {
|
|
|
22905
24004
|
return html4`
|
|
22906
24005
|
<div style="display:flex;flex-direction:column;gap:14px">
|
|
22907
24006
|
${p3.editMode === "yolo" ? html4`<div class="card accent-warn">
|
|
22908
|
-
<div class="card-h"><span class="title" style="color:var(--c-warn)"
|
|
24007
|
+
<div class="card-h"><span class="title" style="color:var(--c-warn)">${t4("permissions.yoloTitle")}</span></div>
|
|
22909
24008
|
<div class="card-b">
|
|
22910
|
-
|
|
22911
|
-
Switch back with <code class="mono">/mode review</code> in the TUI.
|
|
24009
|
+
${t4("permissions.yoloDesc")}
|
|
22912
24010
|
</div>
|
|
22913
24011
|
</div>` : null}
|
|
22914
24012
|
|
|
22915
24013
|
<div class="chips">
|
|
22916
|
-
<span class="chip-f active"
|
|
22917
|
-
<span class="chip-f"
|
|
24014
|
+
<span class="chip-f active">${t4("permissions.project")} <span class="ct">${p3.project.length}</span></span>
|
|
24015
|
+
<span class="chip-f">${t4("permissions.builtin")} <span class="ct">${p3.builtin.length}</span></span>
|
|
22918
24016
|
</div>
|
|
22919
24017
|
|
|
22920
24018
|
${p3.currentCwd ? html4`
|
|
22921
24019
|
<div class="card">
|
|
22922
24020
|
<div class="card-h">
|
|
22923
|
-
<span class="title"
|
|
24021
|
+
<span class="title">${t4("permissions.addPrefix")}</span>
|
|
22924
24022
|
<span class="meta">${p3.currentCwd}</span>
|
|
22925
24023
|
</div>
|
|
22926
24024
|
<div style="display:flex;gap:8px;align-items:center">
|
|
22927
24025
|
<input
|
|
22928
24026
|
type="text"
|
|
22929
|
-
placeholder
|
|
24027
|
+
placeholder=${t4("permissions.addPlaceholder")}
|
|
22930
24028
|
value=${draft}
|
|
22931
24029
|
onInput=${(e3) => setDraft(e3.target.value)}
|
|
22932
24030
|
onKeyDown=${(e3) => {
|
|
@@ -22935,35 +24033,33 @@ function PermissionsPanel() {
|
|
|
22935
24033
|
disabled=${busy}
|
|
22936
24034
|
style="flex:1"
|
|
22937
24035
|
/>
|
|
22938
|
-
<button class="primary" onClick=${add} disabled=${busy || !draft.trim()}
|
|
24036
|
+
<button class="primary" onClick=${add} disabled=${busy || !draft.trim()}>${t4("common.add")}</button>
|
|
22939
24037
|
<button
|
|
22940
24038
|
class="danger"
|
|
22941
24039
|
onClick=${clearAll}
|
|
22942
24040
|
disabled=${busy || p3.project.length === 0}
|
|
22943
|
-
|
|
24041
|
+
>${t4("permissions.clearAll")}</button>
|
|
22944
24042
|
</div>
|
|
22945
24043
|
${feedbackPill ? html4`<div style="margin-top:8px">${feedbackPill}</div>` : null}
|
|
22946
24044
|
</div>
|
|
22947
24045
|
` : html4`
|
|
22948
24046
|
<div class="card accent-warn">
|
|
22949
24047
|
<div class="card-b">
|
|
22950
|
-
|
|
22951
|
-
<code class="mono">reasonix code</code> session — standalone
|
|
22952
|
-
<code class="mono">reasonix dashboard</code> can't tell which project's allowlist to edit.
|
|
24048
|
+
${t4("permissions.standaloneWarning")}
|
|
22953
24049
|
</div>
|
|
22954
24050
|
</div>
|
|
22955
24051
|
`}
|
|
22956
24052
|
|
|
22957
24053
|
<h3 style="margin:6px 0 0;font-family:var(--font-mono);font-size:11px;color:var(--fg-3);text-transform:uppercase;letter-spacing:.1em">
|
|
22958
|
-
|
|
24054
|
+
${t4("permissions.projectAllowlist", { count: p3.project.length })}
|
|
22959
24055
|
</h3>
|
|
22960
|
-
${p3.project.length === 0 ? html4`<div class="card" style="color:var(--fg-3)"
|
|
24056
|
+
${p3.project.length === 0 ? html4`<div class="card" style="color:var(--fg-3)">${t4("permissions.nothingStored")}</div>` : html4`
|
|
22961
24057
|
<div class="card" style="padding:0;overflow:hidden">
|
|
22962
24058
|
<table class="tbl">
|
|
22963
24059
|
<thead>
|
|
22964
24060
|
<tr>
|
|
22965
|
-
<th style="width:48px"
|
|
22966
|
-
<th
|
|
24061
|
+
<th style="width:48px">${t4("permissions.colNum")}</th>
|
|
24062
|
+
<th>${t4("permissions.colPrefix")}</th>
|
|
22967
24063
|
<th style="width:120px"></th>
|
|
22968
24064
|
</tr>
|
|
22969
24065
|
</thead>
|
|
@@ -22978,7 +24074,7 @@ function PermissionsPanel() {
|
|
|
22978
24074
|
class="danger"
|
|
22979
24075
|
onClick=${() => remove(prefix)}
|
|
22980
24076
|
disabled=${busy}
|
|
22981
|
-
|
|
24077
|
+
>${t4("common.remove")}</button>` : null}
|
|
22982
24078
|
</td>
|
|
22983
24079
|
</tr>
|
|
22984
24080
|
`
|
|
@@ -22989,7 +24085,7 @@ function PermissionsPanel() {
|
|
|
22989
24085
|
`}
|
|
22990
24086
|
|
|
22991
24087
|
<h3 style="margin:6px 0 0;font-family:var(--font-mono);font-size:11px;color:var(--fg-3);text-transform:uppercase;letter-spacing:.1em">
|
|
22992
|
-
|
|
24088
|
+
${t4("permissions.builtinTitle", { count: p3.builtin.length })}
|
|
22993
24089
|
</h3>
|
|
22994
24090
|
<div class="card" style="font-family:var(--font-mono);font-size:11.5px;line-height:1.8">
|
|
22995
24091
|
${groupByVerb(p3.builtin).map(
|
|
@@ -23007,22 +24103,22 @@ function PermissionsPanel() {
|
|
|
23007
24103
|
|
|
23008
24104
|
// dashboard/src/panels/plans.ts
|
|
23009
24105
|
function statusPill(p3) {
|
|
23010
|
-
if (p3.completionRatio >= 1) return html4`<span class="pill ok"
|
|
23011
|
-
if (p3.completionRatio > 0) return html4`<span class="pill info"
|
|
24106
|
+
if (p3.completionRatio >= 1) return html4`<span class="pill ok">${t4("plans.done")}</span>`;
|
|
24107
|
+
if (p3.completionRatio > 0) return html4`<span class="pill info">${t4("plans.active")}</span>`;
|
|
23012
24108
|
return html4`<span class="pill">idle</span>`;
|
|
23013
24109
|
}
|
|
23014
24110
|
function PlansPanel() {
|
|
24111
|
+
useLang();
|
|
23015
24112
|
const { data, error, loading } = usePoll("/plans", 8e3);
|
|
23016
24113
|
const [openIdx, setOpenIdx] = p2(null);
|
|
23017
24114
|
const [filter, setFilter] = p2("");
|
|
23018
24115
|
if (loading && !data)
|
|
23019
|
-
return html4`<div class="card" style="color:var(--fg-3)"
|
|
23020
|
-
if (error) return html4`<div class="card accent-err"
|
|
24116
|
+
return html4`<div class="card" style="color:var(--fg-3)">${t4("plans.loading")}</div>`;
|
|
24117
|
+
if (error) return html4`<div class="card accent-err">${t4("common.loadingFailed", { name: "plans", error: error.message })}</div>`;
|
|
23021
24118
|
const plans = data?.plans ?? [];
|
|
23022
24119
|
if (plans.length === 0)
|
|
23023
24120
|
return html4`<div class="card" style="color:var(--fg-3)">
|
|
23024
|
-
|
|
23025
|
-
and <code class="mono">mark_step_complete</code>.
|
|
24121
|
+
${t4("plans.noPlans")}
|
|
23026
24122
|
</div>`;
|
|
23027
24123
|
const filtered = filter.trim() ? plans.filter(
|
|
23028
24124
|
(p3) => p3.session.toLowerCase().includes(filter.toLowerCase()) || (p3.summary ?? "").toLowerCase().includes(filter.toLowerCase())
|
|
@@ -23034,20 +24130,20 @@ function PlansPanel() {
|
|
|
23034
24130
|
<div class="ssl-h">
|
|
23035
24131
|
<input
|
|
23036
24132
|
type="text"
|
|
23037
|
-
placeholder
|
|
24133
|
+
placeholder=${t4("plans.filterPlaceholder")}
|
|
23038
24134
|
value=${filter}
|
|
23039
24135
|
onInput=${(e3) => setFilter(e3.target.value)}
|
|
23040
24136
|
style="flex:1"
|
|
23041
24137
|
/>
|
|
23042
24138
|
</div>
|
|
23043
24139
|
<div class="chips" style="padding:0 12px 8px">
|
|
23044
|
-
<span class="chip-f active"
|
|
24140
|
+
<span class="chip-f active">${t4("common.all")} <span class="ct">${plans.length}</span></span>
|
|
23045
24141
|
<span class="chip-f">
|
|
23046
|
-
active
|
|
24142
|
+
${t4("plans.active")}
|
|
23047
24143
|
<span class="ct">${plans.filter((p3) => p3.completionRatio > 0 && p3.completionRatio < 1).length}</span>
|
|
23048
24144
|
</span>
|
|
23049
24145
|
<span class="chip-f">
|
|
23050
|
-
done <span class="ct">${plans.filter((p3) => p3.completionRatio >= 1).length}</span>
|
|
24146
|
+
${t4("plans.done")} <span class="ct">${plans.filter((p3) => p3.completionRatio >= 1).length}</span>
|
|
23051
24147
|
</span>
|
|
23052
24148
|
</div>
|
|
23053
24149
|
<div class="ssl-rows">
|
|
@@ -23059,7 +24155,7 @@ function PlansPanel() {
|
|
|
23059
24155
|
<span class="name">${p3.summary ?? p3.session} ${statusPill(p3)}</span>
|
|
23060
24156
|
${p3.summary && p3.session !== p3.summary ? html4`<span class="preview">${p3.session}</span>` : null}
|
|
23061
24157
|
<span class="meta">
|
|
23062
|
-
<span><span class="v">${p3.totalSteps}</span> steps</span>
|
|
24158
|
+
<span><span class="v">${p3.totalSteps}</span> ${t4("plans.steps")}</span>
|
|
23063
24159
|
<span><span class="v">${p3.completedSteps} / ${p3.totalSteps}</span> · ${fmtPct(p3.completionRatio)}</span>
|
|
23064
24160
|
<span>${fmtRelativeTime(p3.completedAt)}</span>
|
|
23065
24161
|
</span>
|
|
@@ -23071,18 +24167,18 @@ function PlansPanel() {
|
|
|
23071
24167
|
|
|
23072
24168
|
<div class="sessions-detail">
|
|
23073
24169
|
${open == null ? html4`<div style="color:var(--fg-3);font-size:13px;text-align:center;padding:60px 20px">
|
|
23074
|
-
|
|
24170
|
+
${t4("plans.pickHint")}
|
|
23075
24171
|
</div>` : html4`
|
|
23076
24172
|
<div class="sessions-detail-h">
|
|
23077
|
-
<span class="name">${open.summary ?? "
|
|
24173
|
+
<span class="name">${open.summary ?? t4("plans.noTitle")}</span>
|
|
23078
24174
|
<span class="ws">${open.session} · ${fmtRelativeTime(open.completedAt)}</span>
|
|
23079
24175
|
<span class="actions">
|
|
23080
|
-
<button class="btn ghost" onClick=${() => setOpenIdx(null)}
|
|
24176
|
+
<button class="btn ghost" onClick=${() => setOpenIdx(null)}>${t4("common.back")}</button>
|
|
23081
24177
|
</span>
|
|
23082
24178
|
</div>
|
|
23083
24179
|
|
|
23084
24180
|
<h3 style="margin:0 0 6px;font-family:var(--font-mono);font-size:11px;color:var(--fg-3);text-transform:uppercase;letter-spacing:.1em">
|
|
23085
|
-
|
|
24181
|
+
${t4("plans.stepTimeline", { done: open.completedSteps, total: open.totalSteps })}
|
|
23086
24182
|
</h3>
|
|
23087
24183
|
<div class="plan-timeline" style="margin-bottom:14px">
|
|
23088
24184
|
${open.steps.map((step, i3) => {
|
|
@@ -23090,7 +24186,7 @@ function PlansPanel() {
|
|
|
23090
24186
|
const cls = done ? "done" : i3 === open.completedSteps ? "active" : "";
|
|
23091
24187
|
return html4`
|
|
23092
24188
|
<div class=${`plan-step ${cls}`}>
|
|
23093
|
-
<span class="lbl"
|
|
24189
|
+
<span class="lbl">${t4("plans.step", { n: i3 + 1 })}</span>
|
|
23094
24190
|
<span class="name">${step.title}</span>
|
|
23095
24191
|
${step.action ? html4`<span class="meta">${step.action}</span>` : null}
|
|
23096
24192
|
${step.risk ? html4`<span
|
|
@@ -23109,6 +24205,7 @@ function PlansPanel() {
|
|
|
23109
24205
|
|
|
23110
24206
|
// dashboard/src/panels/semantic.ts
|
|
23111
24207
|
function SemanticPanel() {
|
|
24208
|
+
useLang();
|
|
23112
24209
|
const [data, setData] = p2(null);
|
|
23113
24210
|
const [error, setError] = p2(null);
|
|
23114
24211
|
const [busy, setBusy] = p2(false);
|
|
@@ -23137,7 +24234,7 @@ function SemanticPanel() {
|
|
|
23137
24234
|
setInfo(null);
|
|
23138
24235
|
try {
|
|
23139
24236
|
await api("/semantic/start", { method: "POST", body: { rebuild: !!rebuild } });
|
|
23140
|
-
setInfo(rebuild ? "
|
|
24237
|
+
setInfo(rebuild ? t4("semantic.rebuildStarted") : t4("semantic.incrementalStarted"));
|
|
23141
24238
|
await load();
|
|
23142
24239
|
} catch (err) {
|
|
23143
24240
|
setError(err.message);
|
|
@@ -23152,7 +24249,7 @@ function SemanticPanel() {
|
|
|
23152
24249
|
setError(null);
|
|
23153
24250
|
try {
|
|
23154
24251
|
await api("/semantic/stop", { method: "POST", body: {} });
|
|
23155
|
-
setInfo("
|
|
24252
|
+
setInfo(t4("semantic.stopRequested"));
|
|
23156
24253
|
await load();
|
|
23157
24254
|
} catch (err) {
|
|
23158
24255
|
setError(err.message);
|
|
@@ -23163,11 +24260,11 @@ function SemanticPanel() {
|
|
|
23163
24260
|
const startDaemon = x2(async () => {
|
|
23164
24261
|
setBusy(true);
|
|
23165
24262
|
setError(null);
|
|
23166
|
-
setInfo(
|
|
24263
|
+
setInfo(t4("semantic.startingDaemon"));
|
|
23167
24264
|
try {
|
|
23168
24265
|
const r3 = await api("/semantic/ollama/start", { method: "POST", body: {} });
|
|
23169
24266
|
setInfo(
|
|
23170
|
-
r3.ready ? "
|
|
24267
|
+
r3.ready ? t4("semantic.daemonUp") : t4("semantic.daemonTimeout")
|
|
23171
24268
|
);
|
|
23172
24269
|
await load();
|
|
23173
24270
|
} catch (err) {
|
|
@@ -23180,7 +24277,7 @@ function SemanticPanel() {
|
|
|
23180
24277
|
async (model) => {
|
|
23181
24278
|
setBusy(true);
|
|
23182
24279
|
setError(null);
|
|
23183
|
-
setInfo(
|
|
24280
|
+
setInfo(t4("semantic.pullingModel", { model }));
|
|
23184
24281
|
try {
|
|
23185
24282
|
await api("/semantic/ollama/pull", { method: "POST", body: { model } });
|
|
23186
24283
|
await load();
|
|
@@ -23193,13 +24290,13 @@ function SemanticPanel() {
|
|
|
23193
24290
|
[load]
|
|
23194
24291
|
);
|
|
23195
24292
|
if (!data && !error)
|
|
23196
|
-
return html4`<div class="card" style="color:var(--fg-3)"
|
|
24293
|
+
return html4`<div class="card" style="color:var(--fg-3)">${t4("common.loading")}</div>`;
|
|
23197
24294
|
if (error && !data) return html4`<div class="card accent-err">${error}</div>`;
|
|
23198
24295
|
if (!data) return null;
|
|
23199
24296
|
if (!data.attached) {
|
|
23200
24297
|
return html4`
|
|
23201
24298
|
<div class="card" style="color:var(--fg-3)">
|
|
23202
|
-
<div class="card-h"><span class="title"
|
|
24299
|
+
<div class="card-h"><span class="title">${t4("semantic.codeRequired")}</span></div>
|
|
23203
24300
|
<div class="card-b">${data.reason}</div>
|
|
23204
24301
|
</div>
|
|
23205
24302
|
`;
|
|
@@ -23225,9 +24322,9 @@ function SemanticPanel() {
|
|
|
23225
24322
|
<div style="display:flex;flex-direction:column;gap:10px;min-width:0">
|
|
23226
24323
|
<div class="chips">
|
|
23227
24324
|
<span class=${`chip-f ${idx?.exists ? "active" : ""}`}>
|
|
23228
|
-
${idx?.exists ? "
|
|
24325
|
+
${idx?.exists ? t4("semantic.indexBuilt") : t4("semantic.noIndex")}
|
|
23229
24326
|
</span>
|
|
23230
|
-
${ready ? html4`<span class="chip-f" style="border-color:var(--c-ok);color:var(--c-ok)"
|
|
24327
|
+
${ready ? html4`<span class="chip-f" style="border-color:var(--c-ok);color:var(--c-ok)">${t4("semantic.ready")}</span>` : html4`<span class="chip-f" style="border-color:var(--c-warn);color:var(--c-warn)">${t4("semantic.setupNeeded")}</span>`}
|
|
23231
24328
|
</div>
|
|
23232
24329
|
${info ? html4`<div><span class="pill info">${info}</span></div>` : null}
|
|
23233
24330
|
${error ? html4`<div class="card accent-err">${error}</div>` : null}
|
|
@@ -23236,37 +24333,37 @@ function SemanticPanel() {
|
|
|
23236
24333
|
|
|
23237
24334
|
${!binaryFound ? html4`
|
|
23238
24335
|
<div class="card">
|
|
23239
|
-
<div class="card-h"><span class="title"
|
|
24336
|
+
<div class="card-h"><span class="title">${t4("semantic.installOllama")}</span></div>
|
|
23240
24337
|
<div class="card-b" style="font-size:13px">
|
|
23241
|
-
|
|
24338
|
+
${t4("semantic.installOllamaDesc")}
|
|
23242
24339
|
<ul style="margin:10px 0 4px 18px;padding:0">
|
|
23243
|
-
<li><strong
|
|
23244
|
-
<li><strong
|
|
24340
|
+
<li><strong>${t4("semantic.macWindows")}</strong> ${t4("semantic.download")} <a href="https://ollama.com/download" target="_blank" rel="noreferrer">ollama.com/download</a></li>
|
|
24341
|
+
<li><strong>${t4("semantic.linux")}</strong> <code class="mono">curl -fsSL https://ollama.com/install.sh | sh</code></li>
|
|
23245
24342
|
</ul>
|
|
23246
|
-
<div style="color:var(--fg-3);margin-top:8px"
|
|
24343
|
+
<div style="color:var(--fg-3);margin-top:8px">${t4("semantic.refreshHint", { model: modelName })}</div>
|
|
23247
24344
|
</div>
|
|
23248
24345
|
</div>
|
|
23249
24346
|
` : null}
|
|
23250
24347
|
${binaryFound && !daemonRunning ? html4`
|
|
23251
24348
|
<div class="card">
|
|
23252
|
-
<div class="card-h"><span class="title"
|
|
24349
|
+
<div class="card-h"><span class="title">${t4("semantic.daemon")}</span></div>
|
|
23253
24350
|
<div class="card-b" style="font-size:13px">
|
|
23254
|
-
|
|
24351
|
+
${t4("semantic.daemonDesc")}
|
|
23255
24352
|
<div style="display:flex;gap:8px;margin-top:10px;align-items:center">
|
|
23256
|
-
<button class="primary" disabled=${busy} onClick=${startDaemon}
|
|
23257
|
-
<span style="color:var(--fg-3);font-size:12px"
|
|
24353
|
+
<button class="primary" disabled=${busy} onClick=${startDaemon}>${t4("semantic.startDaemon")}</button>
|
|
24354
|
+
<span style="color:var(--fg-3);font-size:12px">${t4("semantic.runsOllama")}</span>
|
|
23258
24355
|
</div>
|
|
23259
24356
|
</div>
|
|
23260
24357
|
</div>
|
|
23261
24358
|
` : null}
|
|
23262
24359
|
${daemonRunning && !modelPulled ? html4`
|
|
23263
24360
|
<div class="card">
|
|
23264
|
-
<div class="card-h"><span class="title"
|
|
24361
|
+
<div class="card-h"><span class="title">${t4("semantic.model")}</span></div>
|
|
23265
24362
|
<div class="card-b" style="font-size:13px">
|
|
23266
|
-
|
|
24363
|
+
${t4("semantic.modelMissing", { model: modelName })}${pulling ? "" : ` ${t4("semantic.modelSize")}`}
|
|
23267
24364
|
<div style="display:flex;gap:8px;margin-top:10px">
|
|
23268
24365
|
<button class="primary" disabled=${busy || pulling} onClick=${() => pullModel(modelName)}>
|
|
23269
|
-
${pulling ? "pulling
|
|
24366
|
+
${pulling ? t4("semantic.pulling") : t4("semantic.pullModel", { model: modelName })}
|
|
23270
24367
|
</button>
|
|
23271
24368
|
</div>
|
|
23272
24369
|
${pull ? html4`
|
|
@@ -23281,7 +24378,7 @@ function SemanticPanel() {
|
|
|
23281
24378
|
` : null}
|
|
23282
24379
|
|
|
23283
24380
|
${job ? html4`
|
|
23284
|
-
${sectionH3("
|
|
24381
|
+
${sectionH3(t4("semantic.job"))}
|
|
23285
24382
|
<${SemanticJobView} job=${job} running=${running} />
|
|
23286
24383
|
` : null}
|
|
23287
24384
|
</div>
|
|
@@ -23289,43 +24386,43 @@ function SemanticPanel() {
|
|
|
23289
24386
|
<aside style="display:flex;flex-direction:column;gap:10px">
|
|
23290
24387
|
<div class="card">
|
|
23291
24388
|
<div class="card-h">
|
|
23292
|
-
<span class="title"
|
|
24389
|
+
<span class="title">${t4("semantic.indexStatus")}</span>
|
|
23293
24390
|
<span class="meta">
|
|
23294
|
-
${idx?.exists ? html4`<span class="pill ok"
|
|
24391
|
+
${idx?.exists ? html4`<span class="pill ok">${t4("semantic.builtStatus")}</span>` : html4`<span class="pill">${t4("system.none")}</span>`}
|
|
23295
24392
|
</span>
|
|
23296
24393
|
</div>
|
|
23297
24394
|
${idx?.exists ? html4`
|
|
23298
|
-
<div class="rail-kv"><span class="k"
|
|
23299
|
-
<div class="rail-kv"><span class="k"
|
|
23300
|
-
<div class="rail-kv"><span class="k"
|
|
23301
|
-
<div class="rail-kv"><span class="k"
|
|
23302
|
-
<div class="rail-kv"><span class="k"
|
|
23303
|
-
<div class="rail-kv"><span class="k"
|
|
24395
|
+
<div class="rail-kv"><span class="k">${t4("semantic.chunks")}</span><span class="v">${fmtNum(idx.chunks)}</span></div>
|
|
24396
|
+
<div class="rail-kv"><span class="k">${t4("semantic.files")}</span><span class="v">${fmtNum(idx.files)}</span></div>
|
|
24397
|
+
<div class="rail-kv"><span class="k">${t4("semantic.model")}</span><span class="v" style="font-size:11px">${idx.model ?? modelName}</span></div>
|
|
24398
|
+
<div class="rail-kv"><span class="k">${t4("semantic.dim")}</span><span class="v">${fmtNum(idx.dim)}</span></div>
|
|
24399
|
+
<div class="rail-kv"><span class="k">${t4("semantic.size")}</span><span class="v">${fmtBytes(idx.sizeBytes)}</span></div>
|
|
24400
|
+
<div class="rail-kv"><span class="k">${t4("semantic.lastBuild")}</span><span class="v">${fmtRelativeTime(idx.lastBuiltMs ?? null)}</span></div>
|
|
23304
24401
|
` : html4`
|
|
23305
24402
|
<div style="color:var(--fg-3);font-size:12.5px;padding:6px 0">
|
|
23306
|
-
|
|
24403
|
+
${t4("semantic.runIndexHint")}
|
|
23307
24404
|
</div>
|
|
23308
24405
|
`}
|
|
23309
24406
|
<div style="display:flex;gap:6px;margin-top:10px;flex-wrap:wrap">
|
|
23310
|
-
<button class="primary" disabled=${busy || running || !ready} onClick=${() => start(false)}>${idx?.exists ? "
|
|
23311
|
-
${idx?.exists ? html4`<button disabled=${busy || running || !ready} onClick=${() => start(true)}
|
|
23312
|
-
${running ? html4`<button onClick=${stop} style="border-color:var(--c-err);color:var(--c-err)"
|
|
24407
|
+
<button class="primary" disabled=${busy || running || !ready} onClick=${() => start(false)}>${idx?.exists ? t4("semantic.reIndex") : t4("semantic.build")}</button>
|
|
24408
|
+
${idx?.exists ? html4`<button disabled=${busy || running || !ready} onClick=${() => start(true)}>${t4("semantic.rebuild")}</button>` : null}
|
|
24409
|
+
${running ? html4`<button onClick=${stop} style="border-color:var(--c-err);color:var(--c-err)">${t4("semantic.stop")}</button>` : null}
|
|
23313
24410
|
</div>
|
|
23314
24411
|
</div>
|
|
23315
24412
|
|
|
23316
24413
|
<div class="card">
|
|
23317
|
-
<div class="card-h"><span class="title"
|
|
24414
|
+
<div class="card-h"><span class="title">${t4("semantic.ollama")}</span></div>
|
|
23318
24415
|
<div class="rail-kv">
|
|
23319
|
-
<span class="k"
|
|
23320
|
-
<span class="v">${binaryFound ? html4`<span class="pill ok"
|
|
24416
|
+
<span class="k">${t4("semantic.binary")}</span>
|
|
24417
|
+
<span class="v">${binaryFound ? html4`<span class="pill ok">${t4("semantic.found")}</span>` : html4`<span class="pill err">${t4("semantic.missing")}</span>`}</span>
|
|
23321
24418
|
</div>
|
|
23322
24419
|
<div class="rail-kv">
|
|
23323
|
-
<span class="k"
|
|
23324
|
-
<span class="v">${daemonRunning ? html4`<span class="pill ok"
|
|
24420
|
+
<span class="k">${t4("semantic.daemonStatus")}</span>
|
|
24421
|
+
<span class="v">${daemonRunning ? html4`<span class="pill ok">${t4("semantic.up")}</span>` : html4`<span class="pill warn">${t4("semantic.down")}</span>`}</span>
|
|
23325
24422
|
</div>
|
|
23326
24423
|
<div class="rail-kv">
|
|
23327
|
-
<span class="k"
|
|
23328
|
-
<span class="v">${modelPulled ? html4`<span class="pill ok"
|
|
24424
|
+
<span class="k">${t4("semantic.model")}</span>
|
|
24425
|
+
<span class="v">${modelPulled ? html4`<span class="pill ok">${t4("semantic.pulled")}</span>` : html4`<span class="pill warn">${t4("semantic.missing")}</span>`}</span>
|
|
23329
24426
|
</div>
|
|
23330
24427
|
</div>
|
|
23331
24428
|
|
|
@@ -23335,6 +24432,7 @@ function SemanticPanel() {
|
|
|
23335
24432
|
`;
|
|
23336
24433
|
}
|
|
23337
24434
|
function SemanticSearchSection() {
|
|
24435
|
+
useLang();
|
|
23338
24436
|
const [query2, setQuery] = p2("");
|
|
23339
24437
|
const [hits, setHits] = p2(null);
|
|
23340
24438
|
const [meta, setMeta] = p2(null);
|
|
@@ -23367,7 +24465,7 @@ function SemanticSearchSection() {
|
|
|
23367
24465
|
type="text"
|
|
23368
24466
|
class="mono"
|
|
23369
24467
|
style="width:100%;padding:10px 14px 10px 38px;font-size:13.5px;background:var(--bg-input);border:1px solid var(--bd);border-radius:var(--r);color:var(--fg-0);outline:none"
|
|
23370
|
-
placeholder
|
|
24468
|
+
placeholder=${t4("semantic.searchPlaceholder")}
|
|
23371
24469
|
value=${query2}
|
|
23372
24470
|
disabled=${busy}
|
|
23373
24471
|
onInput=${(e3) => setQuery(e3.target.value)}
|
|
@@ -23381,7 +24479,7 @@ function SemanticSearchSection() {
|
|
|
23381
24479
|
</div>
|
|
23382
24480
|
${hits || busy || error ? html4`
|
|
23383
24481
|
<div style="font-family:var(--font-mono);font-size:11px;color:var(--fg-3);margin:8px 0 6px;display:flex;align-items:center;gap:8px">
|
|
23384
|
-
${busy ? html4`<span
|
|
24482
|
+
${busy ? html4`<span>${t4("semantic.searching")}</span>` : error ? html4`<span style="color:var(--c-err)">${error}</span>` : hits ? html4`<span>${t4("semantic.results", { count: hits.length, s: hits.length === 1 ? "" : "s", ms: meta?.elapsedMs ?? 0, model: meta?.model ?? "" })}</span>` : null}
|
|
23385
24483
|
</div>
|
|
23386
24484
|
${hits && hits.length > 0 ? html4`
|
|
23387
24485
|
<div class="card" style="padding:0;max-height:420px;overflow-y:auto">
|
|
@@ -23398,7 +24496,7 @@ function SemanticSearchSection() {
|
|
|
23398
24496
|
`
|
|
23399
24497
|
)}
|
|
23400
24498
|
</div>
|
|
23401
|
-
` : hits && hits.length === 0 && !busy ? html4`<div class="card" style="color:var(--fg-3);font-size:12px"
|
|
24499
|
+
` : hits && hits.length === 0 && !busy ? html4`<div class="card" style="color:var(--fg-3);font-size:12px">${t4("semantic.noMatches")}</div>` : null}
|
|
23402
24500
|
` : null}
|
|
23403
24501
|
</div>
|
|
23404
24502
|
`;
|
|
@@ -23430,6 +24528,7 @@ function fromDraft(d3) {
|
|
|
23430
24528
|
};
|
|
23431
24529
|
}
|
|
23432
24530
|
function SemanticExcludesCard() {
|
|
24531
|
+
useLang();
|
|
23433
24532
|
const [data, setData] = p2(null);
|
|
23434
24533
|
const [draft, setDraft] = p2(null);
|
|
23435
24534
|
const [preview, setPreview] = p2(null);
|
|
@@ -23463,7 +24562,7 @@ function SemanticExcludesCard() {
|
|
|
23463
24562
|
method: "POST",
|
|
23464
24563
|
body: payload
|
|
23465
24564
|
});
|
|
23466
|
-
setInfo(
|
|
24565
|
+
setInfo(t4("semantic.savedConfig", { count: r3.changed.length || 0 }));
|
|
23467
24566
|
await load();
|
|
23468
24567
|
} catch (err) {
|
|
23469
24568
|
setError(err.message);
|
|
@@ -23475,7 +24574,7 @@ function SemanticExcludesCard() {
|
|
|
23475
24574
|
if (!draft) return;
|
|
23476
24575
|
setBusy(true);
|
|
23477
24576
|
setError(null);
|
|
23478
|
-
setInfo("
|
|
24577
|
+
setInfo(t4("semantic.runningPreview"));
|
|
23479
24578
|
try {
|
|
23480
24579
|
const payload = fromDraft(draft);
|
|
23481
24580
|
const r3 = await api("/index-config/preview", {
|
|
@@ -23494,47 +24593,47 @@ function SemanticExcludesCard() {
|
|
|
23494
24593
|
if (!draft) {
|
|
23495
24594
|
return html4`
|
|
23496
24595
|
<div class="card">
|
|
23497
|
-
<div class="card-h"><span class="title"
|
|
23498
|
-
<div style="color:var(--fg-3);font-size:12.5px"
|
|
24596
|
+
<div class="card-h"><span class="title">${t4("semantic.indexConfig")}</span></div>
|
|
24597
|
+
<div style="color:var(--fg-3);font-size:12.5px">${t4("common.loading")}</div>
|
|
23499
24598
|
</div>
|
|
23500
24599
|
`;
|
|
23501
24600
|
}
|
|
23502
24601
|
return html4`
|
|
23503
24602
|
<div class="card">
|
|
23504
24603
|
<div class="card-h">
|
|
23505
|
-
<span class="title"
|
|
24604
|
+
<span class="title">${t4("semantic.indexConfig")}</span>
|
|
23506
24605
|
<span class="meta">
|
|
23507
24606
|
<a
|
|
23508
24607
|
class="mono"
|
|
23509
24608
|
style="color:var(--c-brand);text-decoration:none;font-size:11px;cursor:pointer"
|
|
23510
24609
|
onClick=${reset}
|
|
23511
|
-
|
|
24610
|
+
>${t4("semantic.reset")}</a>
|
|
23512
24611
|
</span>
|
|
23513
24612
|
</div>
|
|
23514
24613
|
${info ? html4`<div style="margin-bottom:8px"><span class="pill ok">${info}</span></div>` : null}
|
|
23515
24614
|
${error ? html4`<div class="card accent-err" style="margin-bottom:8px">${error}</div>` : null}
|
|
23516
24615
|
|
|
23517
24616
|
<${ChipFormRow}
|
|
23518
|
-
label
|
|
24617
|
+
label=${t4("semantic.excludeDirs")}
|
|
23519
24618
|
value=${draft.excludeDirs}
|
|
23520
24619
|
onChange=${(v3) => setDraft({ ...draft, excludeDirs: v3 })}
|
|
23521
24620
|
placeholder="dist"
|
|
23522
24621
|
/>
|
|
23523
24622
|
<${ChipFormRow}
|
|
23524
|
-
label
|
|
24623
|
+
label=${t4("semantic.excludeFiles")}
|
|
23525
24624
|
value=${draft.excludeFiles}
|
|
23526
24625
|
onChange=${(v3) => setDraft({ ...draft, excludeFiles: v3 })}
|
|
23527
24626
|
placeholder="package-lock.json"
|
|
23528
24627
|
/>
|
|
23529
24628
|
<${ChipFormRow}
|
|
23530
|
-
label
|
|
24629
|
+
label=${t4("semantic.excludeExts")}
|
|
23531
24630
|
value=${draft.excludeExts}
|
|
23532
24631
|
onChange=${(v3) => setDraft({ ...draft, excludeExts: v3 })}
|
|
23533
24632
|
placeholder=".lock"
|
|
23534
24633
|
/>
|
|
23535
24634
|
<${ChipFormRow}
|
|
23536
|
-
label
|
|
23537
|
-
sub
|
|
24635
|
+
label=${t4("semantic.excludePatterns")}
|
|
24636
|
+
sub=${t4("semantic.glob")}
|
|
23538
24637
|
value=${draft.excludePatterns}
|
|
23539
24638
|
onChange=${(v3) => setDraft({ ...draft, excludePatterns: v3 })}
|
|
23540
24639
|
placeholder="**/*.test.ts"
|
|
@@ -23546,11 +24645,11 @@ function SemanticExcludesCard() {
|
|
|
23546
24645
|
onClick=${() => setDraft({ ...draft, respectGitignore: !draft.respectGitignore })}
|
|
23547
24646
|
>
|
|
23548
24647
|
<span class=${`box ${draft.respectGitignore ? "on" : ""}`}>${draft.respectGitignore ? "\u2713" : ""}</span>
|
|
23549
|
-
<span
|
|
24648
|
+
<span>${t4("semantic.respectGitignore")}</span>
|
|
23550
24649
|
</div>
|
|
23551
24650
|
|
|
23552
24651
|
<div class="form-row" style="margin-top:10px">
|
|
23553
|
-
<span class="lbl"
|
|
24652
|
+
<span class="lbl">${t4("semantic.maxFileBytes")}</span>
|
|
23554
24653
|
<input
|
|
23555
24654
|
class="input mono"
|
|
23556
24655
|
type="number"
|
|
@@ -23560,14 +24659,14 @@ function SemanticExcludesCard() {
|
|
|
23560
24659
|
onInput=${(e3) => setDraft({ ...draft, maxFileBytes: Number(e3.target.value) || 0 })}
|
|
23561
24660
|
style="font-size:12px"
|
|
23562
24661
|
/>
|
|
23563
|
-
<span class="help"
|
|
24662
|
+
<span class="help">${t4("semantic.skipLarger", { size: (draft.maxFileBytes / 1024 / 1024).toFixed(1) })}</span>
|
|
23564
24663
|
</div>
|
|
23565
24664
|
|
|
23566
24665
|
<div style="display:flex;gap:6px;margin-top:10px">
|
|
23567
24666
|
<button class="btn ghost" style="flex:1" disabled=${busy} onClick=${runPreview}>
|
|
23568
|
-
<span class="g">⊕</span><span
|
|
24667
|
+
<span class="g">⊕</span><span>${t4("semantic.preview")}</span>
|
|
23569
24668
|
</button>
|
|
23570
|
-
<button class="btn primary" style="flex:1" disabled=${busy} onClick=${save}
|
|
24669
|
+
<button class="btn primary" style="flex:1" disabled=${busy} onClick=${save}>${t4("common.save")}</button>
|
|
23571
24670
|
</div>
|
|
23572
24671
|
|
|
23573
24672
|
${preview ? html4`<div style="margin-top:10px"><${ExcludesPreview} preview=${preview} /></div>` : null}
|
|
@@ -23575,6 +24674,7 @@ function SemanticExcludesCard() {
|
|
|
23575
24674
|
`;
|
|
23576
24675
|
}
|
|
23577
24676
|
function ExcludesPreview({ preview }) {
|
|
24677
|
+
useLang();
|
|
23578
24678
|
const buckets = preview.skipBuckets || {};
|
|
23579
24679
|
const samples = preview.skipSamples || {};
|
|
23580
24680
|
const totalSkipped = Object.values(buckets).reduce((a3, b2) => a3 + (b2 || 0), 0);
|
|
@@ -23591,9 +24691,9 @@ function ExcludesPreview({ preview }) {
|
|
|
23591
24691
|
return html4`
|
|
23592
24692
|
<div class="excludes-preview">
|
|
23593
24693
|
<div class="summary">
|
|
23594
|
-
|
|
24694
|
+
${t4("semantic.previewSummary", { included: preview.filesIncluded, skipped: totalSkipped })}
|
|
23595
24695
|
</div>
|
|
23596
|
-
${reasons.length === 0 ? html4`<div style="color:var(--fg-3)"
|
|
24696
|
+
${reasons.length === 0 ? html4`<div style="color:var(--fg-3)">${t4("semantic.nothingSkipped")}</div>` : reasons.map(
|
|
23597
24697
|
(r3) => html4`
|
|
23598
24698
|
<details>
|
|
23599
24699
|
<summary><strong>${r3}: ${buckets[r3]}</strong></summary>
|
|
@@ -23606,7 +24706,7 @@ function ExcludesPreview({ preview }) {
|
|
|
23606
24706
|
)}
|
|
23607
24707
|
${preview.sampleIncluded?.length ? html4`
|
|
23608
24708
|
<details>
|
|
23609
|
-
<summary
|
|
24709
|
+
<summary>${t4("semantic.firstIncluded", { count: preview.sampleIncluded.length })}</summary>
|
|
23610
24710
|
<ul>
|
|
23611
24711
|
${preview.sampleIncluded.map((p3) => html4`<li><code>${p3}</code></li>`)}
|
|
23612
24712
|
</ul>
|
|
@@ -23667,12 +24767,13 @@ function ChipFormRow({
|
|
|
23667
24767
|
`;
|
|
23668
24768
|
}
|
|
23669
24769
|
function SemanticJobView({ job, running }) {
|
|
24770
|
+
useLang();
|
|
23670
24771
|
const phaseLabel = {
|
|
23671
|
-
scan: "
|
|
23672
|
-
embed: "
|
|
23673
|
-
write: "
|
|
23674
|
-
done: "
|
|
23675
|
-
error: "
|
|
24772
|
+
scan: t4("semantic.phaseScan"),
|
|
24773
|
+
embed: t4("semantic.phaseEmbed"),
|
|
24774
|
+
write: t4("semantic.phaseWrite"),
|
|
24775
|
+
done: t4("semantic.phaseDone"),
|
|
24776
|
+
error: t4("semantic.phaseError")
|
|
23676
24777
|
}[job.phase] ?? job.phase;
|
|
23677
24778
|
const total = job.chunksTotal ?? 0;
|
|
23678
24779
|
const doneN = job.chunksDone ?? 0;
|
|
@@ -23682,25 +24783,26 @@ function SemanticJobView({ job, running }) {
|
|
|
23682
24783
|
<div class="kv">
|
|
23683
24784
|
<div><span class="kv-key">phase</span>
|
|
23684
24785
|
<span class=${`pill ${job.phase === "error" ? "pill-err" : running ? "pill-active" : "pill-dim"}`}>${phaseLabel}</span>
|
|
23685
|
-
${job.aborted ? html4`<span class="pill warn" style="margin-left: 6px;"
|
|
24786
|
+
${job.aborted ? html4`<span class="pill warn" style="margin-left: 6px;">${t4("semantic.stopping")}</span>` : null}
|
|
23686
24787
|
<span style="color:var(--fg-3);margin-left:8px">${elapsed}s</span>
|
|
23687
24788
|
</div>
|
|
23688
|
-
${job.filesScanned !== null && job.filesScanned !== void 0 ? html4`<div><span class="kv-key"
|
|
24789
|
+
${job.filesScanned !== null && job.filesScanned !== void 0 ? html4`<div><span class="kv-key">${t4("semantic.files")}</span>${t4("semantic.scanned", { count: job.filesScanned })}${job.filesChanged != null ? ` \xB7 ${t4("semantic.changed", { count: job.filesChanged })}` : ""}${job.filesSkipped ? ` \xB7 ${t4("semantic.skipped", { count: job.filesSkipped })}` : ""}</div>` : null}
|
|
23689
24790
|
${total > 0 ? html4`
|
|
23690
24791
|
<div>
|
|
23691
|
-
<span class="kv-key"
|
|
24792
|
+
<span class="kv-key">${t4("semantic.chunks")}</span>${t4("semantic.chunksProgress", { done: doneN, total, pct: (ratio * 100).toFixed(0) })}
|
|
23692
24793
|
</div>
|
|
23693
24794
|
<div class="bar" style="margin-top: 4px;">
|
|
23694
24795
|
<div class="fill" style=${`width: ${(ratio * 100).toFixed(1)}%; background: var(--primary);`}></div>
|
|
23695
24796
|
</div>
|
|
23696
24797
|
` : null}
|
|
23697
|
-
${job.error ? html4`<div><span class="kv-key"
|
|
23698
|
-
${job.result ? html4`<div><span class="kv-key"
|
|
24798
|
+
${job.error ? html4`<div><span class="kv-key">${t4("semantic.phaseError")}</span><span class="err">${job.error}</span></div>` : null}
|
|
24799
|
+
${job.result ? html4`<div><span class="kv-key">${t4("semantic.result")}</span>${t4("semantic.added", { count: job.result.chunksAdded })} · ${t4("semantic.removed", { count: job.result.chunksRemoved })}${job.result.chunksSkipped ? ` \xB7 ${t4("semantic.failed", { count: job.result.chunksSkipped })}` : ""} · ${(job.result.durationMs / 1e3).toFixed(1)}s</div>` : null}
|
|
23699
24800
|
${job.result?.skipBuckets ? html4`<${SkipBucketsView} buckets=${job.result.skipBuckets} />` : null}
|
|
23700
24801
|
</div>
|
|
23701
24802
|
`;
|
|
23702
24803
|
}
|
|
23703
24804
|
function SkipBucketsView({ buckets }) {
|
|
24805
|
+
useLang();
|
|
23704
24806
|
const order = [
|
|
23705
24807
|
["gitignore", "gitignore"],
|
|
23706
24808
|
["pattern", "pattern"],
|
|
@@ -23714,11 +24816,12 @@ function SkipBucketsView({ buckets }) {
|
|
|
23714
24816
|
const total = order.reduce((a3, [k3]) => a3 + (buckets[k3] || 0), 0);
|
|
23715
24817
|
if (total === 0) return null;
|
|
23716
24818
|
const parts = order.filter(([k3]) => (buckets[k3] || 0) > 0).map(([k3, label]) => `${label}: ${buckets[k3]}`);
|
|
23717
|
-
return html4`<div><span class="kv-key"
|
|
24819
|
+
return html4`<div><span class="kv-key">${t4("semantic.skipped")}</span>${t4("semantic.skippedFiles", { total, details: parts.join(", ") })}</div>`;
|
|
23718
24820
|
}
|
|
23719
24821
|
|
|
23720
24822
|
// dashboard/src/panels/sessions.ts
|
|
23721
24823
|
function SessionsPanel() {
|
|
24824
|
+
useLang();
|
|
23722
24825
|
const { data, error, loading } = usePoll("/sessions", 5e3);
|
|
23723
24826
|
const [open, setOpen] = p2(null);
|
|
23724
24827
|
const [openLoading, setOpenLoading] = p2(false);
|
|
@@ -23736,11 +24839,11 @@ function SessionsPanel() {
|
|
|
23736
24839
|
}
|
|
23737
24840
|
}, []);
|
|
23738
24841
|
if (loading && !data)
|
|
23739
|
-
return html4`<div class="card" style="color:var(--fg-3)"
|
|
23740
|
-
if (error) return html4`<div class="card accent-err"
|
|
24842
|
+
return html4`<div class="card" style="color:var(--fg-3)">${t4("sessions.loading")}</div>`;
|
|
24843
|
+
if (error) return html4`<div class="card accent-err">${t4("common.loadingFailed", { name: "sessions", error: error.message })}</div>`;
|
|
23741
24844
|
const sessions = data?.sessions ?? [];
|
|
23742
24845
|
if (sessions.length === 0)
|
|
23743
|
-
return html4`<div class="card" style="color:var(--fg-3)"
|
|
24846
|
+
return html4`<div class="card" style="color:var(--fg-3)">${t4("sessions.noSessions")}</div>`;
|
|
23744
24847
|
const filtered = filter.trim() ? sessions.filter((s3) => s3.name.toLowerCase().includes(filter.toLowerCase())) : sessions;
|
|
23745
24848
|
return html4`
|
|
23746
24849
|
<div class="sessions-grid">
|
|
@@ -23748,14 +24851,14 @@ function SessionsPanel() {
|
|
|
23748
24851
|
<div class="ssl-h">
|
|
23749
24852
|
<input
|
|
23750
24853
|
type="text"
|
|
23751
|
-
placeholder
|
|
24854
|
+
placeholder=${t4("sessions.filterPlaceholder")}
|
|
23752
24855
|
value=${filter}
|
|
23753
24856
|
onInput=${(e3) => setFilter(e3.target.value)}
|
|
23754
24857
|
style="flex:1"
|
|
23755
24858
|
/>
|
|
23756
24859
|
</div>
|
|
23757
24860
|
<div class="chips" style="padding:0 12px 8px">
|
|
23758
|
-
<span class="chip-f active"
|
|
24861
|
+
<span class="chip-f active">${t4("common.all")} <span class="ct">${sessions.length}</span></span>
|
|
23759
24862
|
</div>
|
|
23760
24863
|
<div class="ssl-rows">
|
|
23761
24864
|
${filtered.map(
|
|
@@ -23766,7 +24869,7 @@ function SessionsPanel() {
|
|
|
23766
24869
|
>
|
|
23767
24870
|
<span class="name">${s3.name}</span>
|
|
23768
24871
|
<span class="meta">
|
|
23769
|
-
<span><span class="v">${fmtNum(s3.messageCount)}</span> msgs</span>
|
|
24872
|
+
<span><span class="v">${fmtNum(s3.messageCount)}</span> ${t4("sessions.msgs")}</span>
|
|
23770
24873
|
<span><span class="v">${fmtBytes(s3.size)}</span></span>
|
|
23771
24874
|
<span>${fmtRelativeTime(s3.mtime)}</span>
|
|
23772
24875
|
</span>
|
|
@@ -23778,25 +24881,25 @@ function SessionsPanel() {
|
|
|
23778
24881
|
|
|
23779
24882
|
<div class="sessions-detail">
|
|
23780
24883
|
${open == null ? html4`<div style="color:var(--fg-3);font-size:13px;text-align:center;padding:60px 20px">
|
|
23781
|
-
|
|
24884
|
+
${t4("sessions.pickHint")}
|
|
23782
24885
|
</div>` : html4`
|
|
23783
24886
|
<div class="sessions-detail-h">
|
|
23784
24887
|
<span class="name">${open.name}</span>
|
|
23785
24888
|
<span class="ws">
|
|
23786
|
-
${open.messages ?
|
|
24889
|
+
${open.messages ? t4("sessions.messages", { count: open.messages.length, s: open.messages.length === 1 ? "" : "s" }) : t4("common.loading")}
|
|
23787
24890
|
</span>
|
|
23788
24891
|
<span class="actions">
|
|
23789
|
-
<button class="btn ghost" onClick=${() => setOpen(null)}
|
|
24892
|
+
<button class="btn ghost" onClick=${() => setOpen(null)}>${t4("common.back")}</button>
|
|
23790
24893
|
</span>
|
|
23791
24894
|
</div>
|
|
23792
24895
|
<div class="card accent-brand" style="margin-bottom:10px">
|
|
23793
|
-
<div class="card-h"><span class="title"
|
|
24896
|
+
<div class="card-h"><span class="title">${t4("sessions.resumeTitle")}</span></div>
|
|
23794
24897
|
<div class="card-b" style="font-size:12.5px;color:var(--fg-2)">
|
|
23795
|
-
|
|
24898
|
+
${t4("sessions.resumeDesc")}
|
|
23796
24899
|
<code class="mono" style="display:block;margin-top:8px;padding:8px 10px;background:var(--bg-input);border-radius:var(--r);color:var(--fg-0);font-size:12px;user-select:all">reasonix chat --session ${open.name}</code>
|
|
23797
24900
|
</div>
|
|
23798
24901
|
</div>
|
|
23799
|
-
${openLoading ? html4`<div style="color:var(--fg-3)"
|
|
24902
|
+
${openLoading ? html4`<div style="color:var(--fg-3)">${t4("sessions.loadingTranscript")}</div>` : open.error ? html4`<div class="card accent-err">${open.error}</div>` : open.messages && open.messages.length > 0 ? html4`<div class="chat-feed" style="max-height:calc(100vh - 220px);overflow-y:auto">
|
|
23800
24903
|
${open.messages.map(
|
|
23801
24904
|
(m2, i3) => html4`
|
|
23802
24905
|
<${ChatMessage}
|
|
@@ -23811,7 +24914,7 @@ function SessionsPanel() {
|
|
|
23811
24914
|
/>
|
|
23812
24915
|
`
|
|
23813
24916
|
)}
|
|
23814
|
-
</div>` : html4`<div style="color:var(--fg-3)"
|
|
24917
|
+
</div>` : html4`<div style="color:var(--fg-3)">${t4("sessions.emptyTranscript")}</div>`}
|
|
23815
24918
|
`}
|
|
23816
24919
|
</div>
|
|
23817
24920
|
</div>
|
|
@@ -23820,6 +24923,7 @@ function SessionsPanel() {
|
|
|
23820
24923
|
|
|
23821
24924
|
// dashboard/src/panels/settings.ts
|
|
23822
24925
|
function SettingsPanel() {
|
|
24926
|
+
useLang();
|
|
23823
24927
|
const [data, setData] = p2(null);
|
|
23824
24928
|
const [error, setError] = p2(null);
|
|
23825
24929
|
const [saving, setSaving] = p2(false);
|
|
@@ -23844,7 +24948,7 @@ function SettingsPanel() {
|
|
|
23844
24948
|
try {
|
|
23845
24949
|
await api("/settings", { method: "POST", body: fields });
|
|
23846
24950
|
await load();
|
|
23847
|
-
setSaved(
|
|
24951
|
+
setSaved(t4("settings.saved", { fields: Object.keys(fields).join(", ") }));
|
|
23848
24952
|
setTimeout(() => setSaved(null), 3e3);
|
|
23849
24953
|
} catch (err) {
|
|
23850
24954
|
setError(err.message);
|
|
@@ -23855,7 +24959,7 @@ function SettingsPanel() {
|
|
|
23855
24959
|
[load]
|
|
23856
24960
|
);
|
|
23857
24961
|
if (!data && !error)
|
|
23858
|
-
return html4`<div class="card" style="color:var(--fg-3)"
|
|
24962
|
+
return html4`<div class="card" style="color:var(--fg-3)">${t4("settings.loading")}</div>`;
|
|
23859
24963
|
if (error && !data) return html4`<div class="card accent-err">${error}</div>`;
|
|
23860
24964
|
if (!data) return null;
|
|
23861
24965
|
const v3 = data;
|
|
@@ -23869,23 +24973,43 @@ function SettingsPanel() {
|
|
|
23869
24973
|
${note ? html4`<span style="color:var(--fg-3);font-size:11px">${note}</span>` : null}
|
|
23870
24974
|
</div>
|
|
23871
24975
|
`;
|
|
24976
|
+
const currentLang2 = getLang();
|
|
23872
24977
|
return html4`
|
|
23873
24978
|
<div style="max-width:760px;display:flex;flex-direction:column;gap:6px">
|
|
23874
24979
|
${saved ? html4`<div><span class="pill ok">${saved}</span></div>` : null}
|
|
23875
24980
|
${error ? html4`<div class="card accent-err">${error}</div>` : null}
|
|
23876
24981
|
|
|
23877
|
-
${sectionH3("
|
|
24982
|
+
${sectionH3(t4("settings.sectionLanguage"))}
|
|
24983
|
+
<div class="card">
|
|
24984
|
+
${fieldRow(
|
|
24985
|
+
t4("settings.language"),
|
|
24986
|
+
html4`
|
|
24987
|
+
<select
|
|
24988
|
+
value=${currentLang2}
|
|
24989
|
+
onChange=${(e3) => {
|
|
24990
|
+
const lang = e3.target.value;
|
|
24991
|
+
setLang(lang);
|
|
24992
|
+
}}
|
|
24993
|
+
>
|
|
24994
|
+
<option value="en">${t4("settings.langEn")}</option>
|
|
24995
|
+
<option value="zh-CN">${t4("settings.langZhCn")}</option>
|
|
24996
|
+
</select>
|
|
24997
|
+
`
|
|
24998
|
+
)}
|
|
24999
|
+
</div>
|
|
25000
|
+
|
|
25001
|
+
${sectionH3(t4("settings.sectionApi"))}
|
|
23878
25002
|
<div class="card">
|
|
23879
25003
|
${fieldRow(
|
|
23880
|
-
"
|
|
23881
|
-
html4`<code class="mono" style="color:var(--fg-2);font-size:11.5px">${v3.apiKey ?? "
|
|
25004
|
+
t4("settings.apiKey"),
|
|
25005
|
+
html4`<code class="mono" style="color:var(--fg-2);font-size:11.5px">${v3.apiKey ?? t4("settings.notSet")}</code>`
|
|
23882
25006
|
)}
|
|
23883
25007
|
${fieldRow(
|
|
23884
|
-
"replace",
|
|
25008
|
+
t4("settings.replace"),
|
|
23885
25009
|
html4`
|
|
23886
25010
|
<input
|
|
23887
25011
|
type="password"
|
|
23888
|
-
placeholder
|
|
25012
|
+
placeholder=${t4("settings.pasteKey")}
|
|
23889
25013
|
value=${draft.apiKey ?? ""}
|
|
23890
25014
|
onInput=${(e3) => setDraft({ ...draft, apiKey: e3.target.value })}
|
|
23891
25015
|
style="flex:1"
|
|
@@ -23894,16 +25018,16 @@ function SettingsPanel() {
|
|
|
23894
25018
|
class="btn primary"
|
|
23895
25019
|
disabled=${saving || !(draft.apiKey ?? "").trim()}
|
|
23896
25020
|
onClick=${() => save({ apiKey: draft.apiKey })}
|
|
23897
|
-
|
|
25021
|
+
>${t4("settings.saveKey")}</button>
|
|
23898
25022
|
`
|
|
23899
25023
|
)}
|
|
23900
25024
|
${fieldRow(
|
|
23901
|
-
"
|
|
25025
|
+
t4("settings.baseUrl"),
|
|
23902
25026
|
html4`
|
|
23903
25027
|
<input
|
|
23904
25028
|
type="text"
|
|
23905
25029
|
value=${draft.baseUrl ?? v3.baseUrl ?? ""}
|
|
23906
|
-
placeholder
|
|
25030
|
+
placeholder=${t4("settings.baseUrlPlaceholder")}
|
|
23907
25031
|
onInput=${(e3) => setDraft({ ...draft, baseUrl: e3.target.value })}
|
|
23908
25032
|
style="flex:1"
|
|
23909
25033
|
/>
|
|
@@ -23911,65 +25035,65 @@ function SettingsPanel() {
|
|
|
23911
25035
|
class="btn"
|
|
23912
25036
|
disabled=${saving || (draft.baseUrl ?? v3.baseUrl ?? "") === (v3.baseUrl ?? "")}
|
|
23913
25037
|
onClick=${() => save({ baseUrl: draft.baseUrl })}
|
|
23914
|
-
|
|
25038
|
+
>${t4("common.save")}</button>
|
|
23915
25039
|
`
|
|
23916
25040
|
)}
|
|
23917
25041
|
</div>
|
|
23918
25042
|
|
|
23919
|
-
${sectionH3("
|
|
25043
|
+
${sectionH3(t4("settings.sectionDefaults"))}
|
|
23920
25044
|
<div class="card">
|
|
23921
25045
|
${fieldRow(
|
|
23922
|
-
"preset",
|
|
25046
|
+
t4("settings.preset"),
|
|
23923
25047
|
html4`
|
|
23924
25048
|
<select
|
|
23925
25049
|
value=${["auto", "flash", "pro"].includes(v3.preset ?? "") ? v3.preset : "auto"}
|
|
23926
25050
|
onChange=${(e3) => save({ preset: e3.target.value })}
|
|
23927
25051
|
disabled=${saving}
|
|
23928
25052
|
>
|
|
23929
|
-
<option value="auto"
|
|
23930
|
-
<option value="flash"
|
|
23931
|
-
<option value="pro"
|
|
25053
|
+
<option value="auto">${t4("settings.presetAuto")}</option>
|
|
25054
|
+
<option value="flash">${t4("settings.presetFlash")}</option>
|
|
25055
|
+
<option value="pro">${t4("settings.presetPro")}</option>
|
|
23932
25056
|
</select>
|
|
23933
25057
|
`,
|
|
23934
|
-
"
|
|
25058
|
+
t4("settings.appliesNextTurn")
|
|
23935
25059
|
)}
|
|
23936
25060
|
${fieldRow(
|
|
23937
|
-
"effort",
|
|
25061
|
+
t4("settings.effort"),
|
|
23938
25062
|
html4`
|
|
23939
25063
|
<select
|
|
23940
25064
|
value=${v3.reasoningEffort}
|
|
23941
25065
|
onChange=${(e3) => save({ reasoningEffort: e3.target.value })}
|
|
23942
25066
|
disabled=${saving}
|
|
23943
25067
|
>
|
|
23944
|
-
<option value="max"
|
|
23945
|
-
<option value="high"
|
|
25068
|
+
<option value="max">${t4("settings.effortMax")}</option>
|
|
25069
|
+
<option value="high">${t4("settings.effortHigh")}</option>
|
|
23946
25070
|
</select>
|
|
23947
25071
|
`,
|
|
23948
|
-
"
|
|
25072
|
+
t4("settings.appliesNextTurn")
|
|
23949
25073
|
)}
|
|
23950
25074
|
${fieldRow(
|
|
23951
|
-
"
|
|
25075
|
+
t4("settings.webSearch"),
|
|
23952
25076
|
html4`
|
|
23953
25077
|
<button
|
|
23954
25078
|
class=${`btn ${v3.search ? "primary" : ""}`}
|
|
23955
25079
|
onClick=${() => save({ search: !v3.search })}
|
|
23956
25080
|
disabled=${saving}
|
|
23957
|
-
>${v3.search ? "
|
|
25081
|
+
>${v3.search ? t4("common.on") : t4("common.off")}</button>
|
|
23958
25082
|
`,
|
|
23959
|
-
"
|
|
25083
|
+
t4("settings.webSearchNote")
|
|
23960
25084
|
)}
|
|
23961
25085
|
</div>
|
|
23962
25086
|
|
|
23963
|
-
${sectionH3("
|
|
25087
|
+
${sectionH3(t4("settings.sectionRuntime"))}
|
|
23964
25088
|
<div class="card">
|
|
23965
25089
|
${fieldRow(
|
|
23966
|
-
"
|
|
25090
|
+
t4("settings.activeModel"),
|
|
23967
25091
|
html4`<code class="mono">${v3.model ?? "\u2014"}</code>`
|
|
23968
25092
|
)}
|
|
23969
25093
|
${fieldRow(
|
|
23970
|
-
"
|
|
25094
|
+
t4("settings.editMode"),
|
|
23971
25095
|
html4`<code class="mono">${v3.editMode}</code>`,
|
|
23972
|
-
"
|
|
25096
|
+
t4("settings.editModeNote")
|
|
23973
25097
|
)}
|
|
23974
25098
|
</div>
|
|
23975
25099
|
</div>
|
|
@@ -23978,6 +25102,7 @@ function SettingsPanel() {
|
|
|
23978
25102
|
|
|
23979
25103
|
// dashboard/src/panels/skills.ts
|
|
23980
25104
|
function SkillsPanel() {
|
|
25105
|
+
useLang();
|
|
23981
25106
|
const [data, setData] = p2(null);
|
|
23982
25107
|
const [error, setError] = p2(null);
|
|
23983
25108
|
const [open, setOpen] = p2(null);
|
|
@@ -24021,7 +25146,7 @@ function SkillsPanel() {
|
|
|
24021
25146
|
method: "POST",
|
|
24022
25147
|
body: { body }
|
|
24023
25148
|
});
|
|
24024
|
-
setInfo(
|
|
25149
|
+
setInfo(t4("skills.saved", { scope: open.scope, name: open.name }));
|
|
24025
25150
|
setTimeout(() => setInfo(null), 3e3);
|
|
24026
25151
|
await load();
|
|
24027
25152
|
} catch (err) {
|
|
@@ -24032,7 +25157,7 @@ function SkillsPanel() {
|
|
|
24032
25157
|
}, [open, body, load]);
|
|
24033
25158
|
const remove = x2(async () => {
|
|
24034
25159
|
if (!open) return;
|
|
24035
|
-
if (!confirm(
|
|
25160
|
+
if (!confirm(t4("skills.deleteConfirm", { scope: open.scope, name: open.name }))) return;
|
|
24036
25161
|
setBusy(true);
|
|
24037
25162
|
try {
|
|
24038
25163
|
await api(`/skills/${open.scope}/${encodeURIComponent(open.name)}`, { method: "DELETE" });
|
|
@@ -24070,7 +25195,7 @@ description: TODO \u2014 one-line description that helps the model match this sk
|
|
|
24070
25195
|
}
|
|
24071
25196
|
}, [newName, newScope, load, openSkill]);
|
|
24072
25197
|
if (!data && !error)
|
|
24073
|
-
return html4`<div class="card" style="color:var(--fg-3)"
|
|
25198
|
+
return html4`<div class="card" style="color:var(--fg-3)">${t4("skills.loading")}</div>`;
|
|
24074
25199
|
if (error && !data) return html4`<div class="card accent-err">${error}</div>`;
|
|
24075
25200
|
if (!data) return null;
|
|
24076
25201
|
const allWith = [
|
|
@@ -24087,17 +25212,17 @@ description: TODO \u2014 one-line description that helps the model match this sk
|
|
|
24087
25212
|
<div class="ssl-h">
|
|
24088
25213
|
<input
|
|
24089
25214
|
type="text"
|
|
24090
|
-
placeholder
|
|
25215
|
+
placeholder=${t4("skills.filterPlaceholder")}
|
|
24091
25216
|
value=${filter}
|
|
24092
25217
|
onInput=${(e3) => setFilter(e3.target.value)}
|
|
24093
25218
|
style="flex:1"
|
|
24094
25219
|
/>
|
|
24095
25220
|
</div>
|
|
24096
25221
|
<div class="chips" style="padding:0 12px 8px">
|
|
24097
|
-
<span class="chip-f active"
|
|
24098
|
-
<span class="chip-f"
|
|
24099
|
-
<span class="chip-f"
|
|
24100
|
-
<span class="chip-f"
|
|
25222
|
+
<span class="chip-f active">${t4("common.all")} <span class="ct">${allWith.length}</span></span>
|
|
25223
|
+
<span class="chip-f">${t4("skills.project")} <span class="ct">${data.project.length}</span></span>
|
|
25224
|
+
<span class="chip-f">${t4("skills.global")} <span class="ct">${data.global.length}</span></span>
|
|
25225
|
+
<span class="chip-f">${t4("skills.builtin")} <span class="ct">${data.builtin.length}</span></span>
|
|
24101
25226
|
</div>
|
|
24102
25227
|
|
|
24103
25228
|
<div style="padding:0 12px 8px;display:flex;gap:6px;flex-wrap:wrap">
|
|
@@ -24106,12 +25231,12 @@ description: TODO \u2014 one-line description that helps the model match this sk
|
|
|
24106
25231
|
onChange=${(e3) => setNewScope(e3.target.value)}
|
|
24107
25232
|
style="flex:0 0 auto;font-size:11.5px;padding:5px 6px"
|
|
24108
25233
|
>
|
|
24109
|
-
<option value="global"
|
|
24110
|
-
${data.paths.project ? html4`<option value="project"
|
|
25234
|
+
<option value="global">${t4("skills.global")}</option>
|
|
25235
|
+
${data.paths.project ? html4`<option value="project">${t4("skills.project")}</option>` : null}
|
|
24111
25236
|
</select>
|
|
24112
25237
|
<input
|
|
24113
25238
|
type="text"
|
|
24114
|
-
placeholder
|
|
25239
|
+
placeholder=${t4("skills.newSkill")}
|
|
24115
25240
|
value=${newName}
|
|
24116
25241
|
onInput=${(e3) => setNewName(e3.target.value)}
|
|
24117
25242
|
style="flex:1;min-width:0"
|
|
@@ -24129,11 +25254,11 @@ description: TODO \u2014 one-line description that helps the model match this sk
|
|
|
24129
25254
|
>
|
|
24130
25255
|
<span class="name">
|
|
24131
25256
|
${s3.name}
|
|
24132
|
-
${s3.scope === "builtin" ? html4`<span class="pill"
|
|
25257
|
+
${s3.scope === "builtin" ? html4`<span class="pill">${t4("skills.builtin")}</span>` : null}
|
|
24133
25258
|
</span>
|
|
24134
|
-
<span class="preview">${s3.description ?? "
|
|
25259
|
+
<span class="preview">${s3.description ?? t4("skills.noDescription")}</span>
|
|
24135
25260
|
<span class="meta">
|
|
24136
|
-
${typeof s3.runs7d === "number" && s3.runs7d > 0 ? html4`<span><span class="v">${s3.runs7d}</span>
|
|
25261
|
+
${typeof s3.runs7d === "number" && s3.runs7d > 0 ? html4`<span><span class="v">${s3.runs7d}</span> ${t4("skills.runs7d")}</span>` : null}
|
|
24137
25262
|
<span class="dim">${s3.scope}</span>
|
|
24138
25263
|
</span>
|
|
24139
25264
|
</div>
|
|
@@ -24144,22 +25269,22 @@ description: TODO \u2014 one-line description that helps the model match this sk
|
|
|
24144
25269
|
|
|
24145
25270
|
<div class="sessions-detail">
|
|
24146
25271
|
${open == null ? html4`<div style="color:var(--fg-3);font-size:13px;text-align:center;padding:60px 20px">
|
|
24147
|
-
|
|
25272
|
+
${t4("skills.pickHint")}
|
|
24148
25273
|
</div>` : open.scope === "builtin" ? (() => {
|
|
24149
25274
|
const builtin = data.builtin.find((b2) => b2.name === open.name);
|
|
24150
25275
|
return html4`
|
|
24151
25276
|
<div class="sessions-detail-h">
|
|
24152
25277
|
<span class="name">${open.scope}/${open.name}</span>
|
|
24153
|
-
<span class="ws"><span class="pill"
|
|
25278
|
+
<span class="ws"><span class="pill">${t4("skills.readOnlyBuiltin")}</span></span>
|
|
24154
25279
|
<span class="actions">
|
|
24155
|
-
<button class="btn ghost" onClick=${() => setOpen(null)}
|
|
25280
|
+
<button class="btn ghost" onClick=${() => setOpen(null)}>${t4("common.back")}</button>
|
|
24156
25281
|
</span>
|
|
24157
25282
|
</div>
|
|
24158
25283
|
<div style="color:var(--fg-2);font-size:13px;line-height:1.6">
|
|
24159
|
-
${builtin?.description ?? "
|
|
25284
|
+
${builtin?.description ?? t4("skills.noDescription")}
|
|
24160
25285
|
</div>
|
|
24161
25286
|
<div style="margin-top:14px;color:var(--fg-3);font-size:11.5px">
|
|
24162
|
-
|
|
25287
|
+
${t4("skills.builtinDesc")}
|
|
24163
25288
|
</div>
|
|
24164
25289
|
`;
|
|
24165
25290
|
})() : html4`
|
|
@@ -24167,10 +25292,10 @@ description: TODO \u2014 one-line description that helps the model match this sk
|
|
|
24167
25292
|
<span class="name">${open.scope}/${open.name}</span>
|
|
24168
25293
|
<span class="ws">${body.length.toLocaleString()} chars</span>
|
|
24169
25294
|
<span class="actions">
|
|
24170
|
-
<button class="btn primary" disabled=${busy} onClick=${save}
|
|
25295
|
+
<button class="btn primary" disabled=${busy} onClick=${save}>${t4("common.save")}</button>
|
|
24171
25296
|
<button class="btn" disabled=${busy} onClick=${remove}
|
|
24172
|
-
style="border-color:var(--c-err);color:var(--c-err)"
|
|
24173
|
-
<button class="btn ghost" onClick=${() => setOpen(null)}
|
|
25297
|
+
style="border-color:var(--c-err);color:var(--c-err)">${t4("common.delete")}</button>
|
|
25298
|
+
<button class="btn ghost" onClick=${() => setOpen(null)}>${t4("common.back")}</button>
|
|
24174
25299
|
</span>
|
|
24175
25300
|
</div>
|
|
24176
25301
|
${info ? html4`<div style="margin-bottom:8px"><span class="pill ok">${info}</span></div>` : null}
|
|
@@ -24182,7 +25307,7 @@ description: TODO \u2014 one-line description that helps the model match this sk
|
|
|
24182
25307
|
disabled=${busy}
|
|
24183
25308
|
></textarea>
|
|
24184
25309
|
<div style="margin-top:8px;color:var(--fg-3);font-size:11.5px">
|
|
24185
|
-
|
|
25310
|
+
${t4("skills.reloadHint")}
|
|
24186
25311
|
</div>
|
|
24187
25312
|
`}
|
|
24188
25313
|
</div>
|
|
@@ -24192,76 +25317,77 @@ description: TODO \u2014 one-line description that helps the model match this sk
|
|
|
24192
25317
|
|
|
24193
25318
|
// dashboard/src/panels/system.ts
|
|
24194
25319
|
function SystemPanel() {
|
|
25320
|
+
useLang();
|
|
24195
25321
|
const { data, error, loading } = usePoll("/health", 5e3);
|
|
24196
25322
|
if (loading && !data)
|
|
24197
|
-
return html4`<div class="card" style="color:var(--fg-3)"
|
|
24198
|
-
if (error) return html4`<div class="card accent-err"
|
|
25323
|
+
return html4`<div class="card" style="color:var(--fg-3)">${t4("system.loading")}</div>`;
|
|
25324
|
+
if (error) return html4`<div class="card accent-err">${t4("common.loadingFailed", { name: "health", error: error.message })}</div>`;
|
|
24199
25325
|
if (!data) return null;
|
|
24200
25326
|
const h3 = data;
|
|
24201
25327
|
const upToDate = h3.latestVersion ? h3.latestVersion === h3.version : null;
|
|
24202
25328
|
return html4`
|
|
24203
25329
|
<div style="display:flex;flex-direction:column;gap:14px">
|
|
24204
|
-
<h3 style="margin:0;font-family:var(--font-mono);font-size:11px;color:var(--fg-3);text-transform:uppercase;letter-spacing:.1em"
|
|
25330
|
+
<h3 style="margin:0;font-family:var(--font-mono);font-size:11px;color:var(--fg-3);text-transform:uppercase;letter-spacing:.1em">${t4("system.healthChecks")}</h3>
|
|
24205
25331
|
<div class="health-grid">
|
|
24206
25332
|
<div class=${`health-item ${upToDate === false ? "warn" : ""}`}>
|
|
24207
25333
|
<div class="lbl">
|
|
24208
|
-
version
|
|
24209
|
-
${upToDate === null ? html4`<span class="pill"
|
|
25334
|
+
${t4("system.version")}
|
|
25335
|
+
${upToDate === null ? html4`<span class="pill">${t4("system.checking")}</span>` : upToDate ? html4`<span class="pill ok">${t4("system.latest")}</span>` : html4`<span class="pill warn">${t4("system.outOfDate")}</span>`}
|
|
24210
25336
|
</div>
|
|
24211
25337
|
<div class="v">${h3.version}</div>
|
|
24212
|
-
<div class="meta">${upToDate === null ? "
|
|
25338
|
+
<div class="meta">${upToDate === null ? t4("system.versionPending") : upToDate ? t4("system.upToDate") : t4("system.latestVer", { version: h3.latestVersion ?? "" })}</div>
|
|
24213
25339
|
</div>
|
|
24214
25340
|
|
|
24215
25341
|
<div class="health-item">
|
|
24216
|
-
<div class="lbl"
|
|
25342
|
+
<div class="lbl">${t4("system.sessions")} <span class="pill ok">${t4("system.ok")}</span></div>
|
|
24217
25343
|
<div class="v">${fmtBytes(h3.sessions.totalBytes)}</div>
|
|
24218
|
-
<div class="meta">${fmtNum(h3.sessions.count)} files</div>
|
|
25344
|
+
<div class="meta">${fmtNum(h3.sessions.count)} ${t4("system.files")}</div>
|
|
24219
25345
|
</div>
|
|
24220
25346
|
|
|
24221
25347
|
<div class="health-item">
|
|
24222
|
-
<div class="lbl"
|
|
25348
|
+
<div class="lbl">${t4("system.memory")} <span class="pill ok">${t4("system.ok")}</span></div>
|
|
24223
25349
|
<div class="v">${fmtBytes(h3.memory.totalBytes)}</div>
|
|
24224
|
-
<div class="meta">${fmtNum(h3.memory.fileCount)} files</div>
|
|
25350
|
+
<div class="meta">${fmtNum(h3.memory.fileCount)} ${t4("system.files")}</div>
|
|
24225
25351
|
</div>
|
|
24226
25352
|
|
|
24227
25353
|
<div class="health-item">
|
|
24228
25354
|
<div class="lbl">
|
|
24229
|
-
|
|
24230
|
-
${h3.semantic.exists ? html4`<span class="pill ok"
|
|
25355
|
+
${t4("system.semanticIndex")}
|
|
25356
|
+
${h3.semantic.exists ? html4`<span class="pill ok">${t4("system.built")}</span>` : html4`<span class="pill">${t4("system.none")}</span>`}
|
|
24231
25357
|
</div>
|
|
24232
25358
|
<div class="v">${h3.semantic.exists ? fmtBytes(h3.semantic.totalBytes) : "\u2014"}</div>
|
|
24233
25359
|
<div class="meta">
|
|
24234
|
-
${h3.semantic.exists ? `${fmtNum(h3.semantic.fileCount)} files` : "
|
|
25360
|
+
${h3.semantic.exists ? `${fmtNum(h3.semantic.fileCount)} ${t4("system.files")}` : t4("system.runIndex")}
|
|
24235
25361
|
</div>
|
|
24236
25362
|
</div>
|
|
24237
25363
|
|
|
24238
25364
|
<div class="health-item">
|
|
24239
|
-
<div class="lbl"
|
|
25365
|
+
<div class="lbl">${t4("system.usageLog")} <span class="pill ok">${t4("system.ok")}</span></div>
|
|
24240
25366
|
<div class="v">${fmtBytes(h3.usageLog.bytes)}</div>
|
|
24241
25367
|
<div class="meta">~/.reasonix/usage.jsonl</div>
|
|
24242
25368
|
</div>
|
|
24243
25369
|
|
|
24244
25370
|
<div class="health-item">
|
|
24245
25371
|
<div class="lbl">
|
|
24246
|
-
|
|
24247
|
-
${h3.jobs === null ? html4`<span class="pill"
|
|
25372
|
+
${t4("system.backgroundJobs")}
|
|
25373
|
+
${h3.jobs === null ? html4`<span class="pill">${t4("system.noSession")}</span>` : html4`<span class="pill ok">● ${fmtNum(h3.jobs)}</span>`}
|
|
24248
25374
|
</div>
|
|
24249
|
-
<div class="v">${h3.jobs === null ? "\u2014" :
|
|
24250
|
-
<div class="meta">${h3.jobs === null ? "
|
|
25375
|
+
<div class="v">${h3.jobs === null ? "\u2014" : t4("system.running", { count: fmtNum(h3.jobs) })}</div>
|
|
25376
|
+
<div class="meta">${h3.jobs === null ? t4("system.attachHint") : t4("system.shellSpawn")}</div>
|
|
24251
25377
|
</div>
|
|
24252
25378
|
</div>
|
|
24253
25379
|
|
|
24254
25380
|
<div class="card" style="padding:0">
|
|
24255
25381
|
<div class="card-h" style="padding:12px 14px 6px">
|
|
24256
|
-
<span class="title"
|
|
25382
|
+
<span class="title">${t4("system.paths")}</span>
|
|
24257
25383
|
</div>
|
|
24258
25384
|
<table class="tbl">
|
|
24259
25385
|
<tbody style="font-size:11.5px">
|
|
24260
|
-
<tr><td class="dim" style="padding:5px 14px"
|
|
24261
|
-
<tr><td class="dim" style="padding:5px 14px"
|
|
24262
|
-
<tr><td class="dim" style="padding:5px 14px"
|
|
24263
|
-
<tr><td class="dim" style="padding:5px 14px"
|
|
24264
|
-
<tr><td class="dim" style="padding:5px 14px"
|
|
25386
|
+
<tr><td class="dim" style="padding:5px 14px">${t4("system.home")}</td><td class="path">${h3.reasonixHome}</td></tr>
|
|
25387
|
+
<tr><td class="dim" style="padding:5px 14px">${t4("system.sessionsPath")}</td><td class="path">${h3.sessions.path}</td></tr>
|
|
25388
|
+
<tr><td class="dim" style="padding:5px 14px">${t4("system.memoryPath")}</td><td class="path">${h3.memory.path}</td></tr>
|
|
25389
|
+
<tr><td class="dim" style="padding:5px 14px">${t4("system.semanticPath")}</td><td class="path">${h3.semantic.path}</td></tr>
|
|
25390
|
+
<tr><td class="dim" style="padding:5px 14px">${t4("system.usagePath")}</td><td class="path">${h3.usageLog.path}</td></tr>
|
|
24265
25391
|
</tbody>
|
|
24266
25392
|
</table>
|
|
24267
25393
|
</div>
|
|
@@ -24271,41 +25397,42 @@ function SystemPanel() {
|
|
|
24271
25397
|
|
|
24272
25398
|
// dashboard/src/panels/tools.ts
|
|
24273
25399
|
function ToolsPanel() {
|
|
25400
|
+
useLang();
|
|
24274
25401
|
const { data, error, loading } = usePoll("/tools", 4e3);
|
|
24275
25402
|
if (loading && !data)
|
|
24276
|
-
return html4`<div class="card" style="color:var(--fg-3)"
|
|
25403
|
+
return html4`<div class="card" style="color:var(--fg-3)">${t4("tools.loading")}</div>`;
|
|
24277
25404
|
const e3 = error;
|
|
24278
25405
|
if (e3?.status === 503) {
|
|
24279
|
-
return html4`<div class="card accent-warn">${e3.body?.error ?? "
|
|
25406
|
+
return html4`<div class="card accent-warn">${e3.body?.error ?? t4("common.loadingFailed", { name: "tools", error: "" })}</div>`;
|
|
24280
25407
|
}
|
|
24281
|
-
if (e3) return html4`<div class="card accent-err"
|
|
25408
|
+
if (e3) return html4`<div class="card accent-err">${t4("common.loadingFailed", { name: "tools", error: e3.message })}</div>`;
|
|
24282
25409
|
if (!data) return null;
|
|
24283
|
-
const
|
|
25410
|
+
const d3 = data;
|
|
24284
25411
|
return html4`
|
|
24285
25412
|
<div style="display:flex;flex-direction:column;gap:14px">
|
|
24286
25413
|
<div class="chips">
|
|
24287
|
-
<span class="chip-f active"
|
|
24288
|
-
${
|
|
25414
|
+
<span class="chip-f active">${t4("common.all")} <span class="ct">${d3.total}</span></span>
|
|
25415
|
+
${d3.planMode ? html4`<span class="chip-f" style="border-color:var(--c-warn);color:var(--c-warn)">${t4("tools.planMode")}</span>` : null}
|
|
24289
25416
|
</div>
|
|
24290
25417
|
|
|
24291
|
-
${
|
|
25418
|
+
${d3.tools.length === 0 ? html4`<div class="card" style="color:var(--fg-3)">${t4("tools.noTools")}</div>` : html4`
|
|
24292
25419
|
<div class="card" style="padding:0;overflow:hidden">
|
|
24293
25420
|
<table class="tbl">
|
|
24294
25421
|
<thead>
|
|
24295
25422
|
<tr>
|
|
24296
|
-
<th
|
|
24297
|
-
<th
|
|
24298
|
-
<th
|
|
25423
|
+
<th>${t4("tools.colTool")}</th>
|
|
25424
|
+
<th>${t4("tools.colFlags")}</th>
|
|
25425
|
+
<th>${t4("tools.colDesc")}</th>
|
|
24299
25426
|
</tr>
|
|
24300
25427
|
</thead>
|
|
24301
25428
|
<tbody>
|
|
24302
|
-
${
|
|
25429
|
+
${d3.tools.map(
|
|
24303
25430
|
(tool) => html4`
|
|
24304
25431
|
<tr>
|
|
24305
25432
|
<td><code class="mono">${tool.name}</code></td>
|
|
24306
25433
|
<td>
|
|
24307
|
-
${tool.readOnly ? html4`<span class="pill ok"
|
|
24308
|
-
${tool.flattened ? html4` <span class="pill"
|
|
25434
|
+
${tool.readOnly ? html4`<span class="pill ok">${t4("tools.readOnly")}</span>` : html4`<span class="pill acc">${t4("tools.write")}</span>`}
|
|
25435
|
+
${tool.flattened ? html4` <span class="pill">${t4("tools.flat")}</span>` : null}
|
|
24309
25436
|
</td>
|
|
24310
25437
|
<td class="dim">${tool.description ?? ""}</td>
|
|
24311
25438
|
</tr>
|
|
@@ -24406,6 +25533,7 @@ function UsageChart({ days: days2 }) {
|
|
|
24406
25533
|
return html4`<div ref=${containerRef} style="width: 100%; min-height: 280px;"></div>`;
|
|
24407
25534
|
}
|
|
24408
25535
|
function UsagePanel() {
|
|
25536
|
+
useLang();
|
|
24409
25537
|
const { data: summary, error, loading } = usePoll("/usage", 5e3);
|
|
24410
25538
|
const [series, setSeries] = p2(null);
|
|
24411
25539
|
_2(() => {
|
|
@@ -24417,7 +25545,7 @@ function UsagePanel() {
|
|
|
24417
25545
|
} catch {
|
|
24418
25546
|
}
|
|
24419
25547
|
})();
|
|
24420
|
-
const
|
|
25548
|
+
const interval = setInterval(async () => {
|
|
24421
25549
|
try {
|
|
24422
25550
|
const s3 = await api("/usage/series");
|
|
24423
25551
|
if (!cancelled) setSeries(s3.days ?? []);
|
|
@@ -24426,12 +25554,12 @@ function UsagePanel() {
|
|
|
24426
25554
|
}, 3e4);
|
|
24427
25555
|
return () => {
|
|
24428
25556
|
cancelled = true;
|
|
24429
|
-
clearInterval(
|
|
25557
|
+
clearInterval(interval);
|
|
24430
25558
|
};
|
|
24431
25559
|
}, []);
|
|
24432
25560
|
if (loading && !summary)
|
|
24433
|
-
return html4`<div class="card" style="color:var(--fg-3)"
|
|
24434
|
-
if (error) return html4`<div class="card accent-err"
|
|
25561
|
+
return html4`<div class="card" style="color:var(--fg-3)">${t4("usage.loading")}</div>`;
|
|
25562
|
+
if (error) return html4`<div class="card accent-err">${t4("common.loadingFailed", { name: "usage", error: error.message })}</div>`;
|
|
24435
25563
|
if (!summary) return null;
|
|
24436
25564
|
const u3 = summary;
|
|
24437
25565
|
const sectionH3 = (text) => html4`
|
|
@@ -24440,36 +25568,35 @@ function UsagePanel() {
|
|
|
24440
25568
|
return html4`
|
|
24441
25569
|
<div style="display:flex;flex-direction:column;gap:6px">
|
|
24442
25570
|
<div class="chips">
|
|
24443
|
-
<span class="chip-f active">${u3.recordCount.toLocaleString()}
|
|
25571
|
+
<span class="chip-f active">${t4("usage.records", { count: u3.recordCount.toLocaleString() })}</span>
|
|
24444
25572
|
<span class="chip-f">${u3.logSize}</span>
|
|
24445
25573
|
</div>
|
|
24446
25574
|
|
|
24447
25575
|
${series && series.length > 0 ? html4`
|
|
24448
25576
|
<div class="card" style="padding:18px">
|
|
24449
25577
|
<div class="card-h">
|
|
24450
|
-
<span class="title"
|
|
24451
|
-
<span class="meta"
|
|
25578
|
+
<span class="title">${t4("usage.dailyUsage")}</span>
|
|
25579
|
+
<span class="meta">${t4("usage.dailyMeta")}</span>
|
|
24452
25580
|
</div>
|
|
24453
25581
|
<${UsageChart} days=${series} />
|
|
24454
25582
|
</div>
|
|
24455
25583
|
` : null}
|
|
24456
25584
|
|
|
24457
25585
|
${u3.recordCount === 0 ? html4`<div class="card" style="color:var(--fg-3);margin-top:8px">
|
|
24458
|
-
|
|
24459
|
-
<code class="mono">code</code> / <code class="mono">run</code> and refresh.
|
|
25586
|
+
${t4("usage.noData")}
|
|
24460
25587
|
</div>` : html4`
|
|
24461
|
-
${sectionH3("
|
|
25588
|
+
${sectionH3(t4("usage.windows"))}
|
|
24462
25589
|
<div class="card" style="padding:0;overflow:hidden">
|
|
24463
25590
|
<table class="tbl">
|
|
24464
25591
|
<thead>
|
|
24465
25592
|
<tr>
|
|
24466
25593
|
<th></th>
|
|
24467
|
-
<th
|
|
24468
|
-
<th
|
|
24469
|
-
<th
|
|
24470
|
-
<th
|
|
24471
|
-
<th
|
|
24472
|
-
<th
|
|
25594
|
+
<th>${t4("usage.colTurns")}</th>
|
|
25595
|
+
<th>${t4("usage.colCacheHit")}</th>
|
|
25596
|
+
<th>${t4("usage.colCost")}</th>
|
|
25597
|
+
<th>${t4("usage.colCacheSaved")}</th>
|
|
25598
|
+
<th>${t4("usage.colVsClaude")}</th>
|
|
25599
|
+
<th>${t4("usage.colSaved")}</th>
|
|
24473
25600
|
</tr>
|
|
24474
25601
|
</thead>
|
|
24475
25602
|
<tbody>
|
|
@@ -24494,13 +25621,13 @@ function UsagePanel() {
|
|
|
24494
25621
|
`}
|
|
24495
25622
|
|
|
24496
25623
|
${u3.byModel.length > 0 ? html4`
|
|
24497
|
-
${sectionH3("
|
|
25624
|
+
${sectionH3(t4("usage.mostUsed"))}
|
|
24498
25625
|
<div class="card" style="padding:0;overflow:hidden">
|
|
24499
25626
|
<table class="tbl">
|
|
24500
25627
|
<thead>
|
|
24501
25628
|
<tr>
|
|
24502
|
-
<th
|
|
24503
|
-
<th
|
|
25629
|
+
<th>${t4("usage.colModel")}</th>
|
|
25630
|
+
<th>${t4("usage.colTurns")}</th>
|
|
24504
25631
|
</tr>
|
|
24505
25632
|
</thead>
|
|
24506
25633
|
<tbody>
|
|
@@ -24522,40 +25649,51 @@ function UsagePanel() {
|
|
|
24522
25649
|
|
|
24523
25650
|
// dashboard/app.js
|
|
24524
25651
|
var html5 = htm_module_default.bind(_);
|
|
24525
|
-
|
|
24526
|
-
|
|
24527
|
-
|
|
24528
|
-
|
|
24529
|
-
|
|
24530
|
-
|
|
24531
|
-
|
|
24532
|
-
|
|
24533
|
-
|
|
24534
|
-
|
|
24535
|
-
|
|
24536
|
-
|
|
24537
|
-
|
|
24538
|
-
|
|
24539
|
-
|
|
24540
|
-
|
|
24541
|
-
|
|
24542
|
-
|
|
24543
|
-
|
|
24544
|
-
|
|
24545
|
-
|
|
24546
|
-
|
|
24547
|
-
|
|
24548
|
-
|
|
24549
|
-
|
|
24550
|
-
|
|
24551
|
-
|
|
24552
|
-
|
|
24553
|
-
|
|
24554
|
-
|
|
24555
|
-
|
|
24556
|
-
|
|
25652
|
+
function tabSections() {
|
|
25653
|
+
return [
|
|
25654
|
+
{
|
|
25655
|
+
label: t4("app.sectionWorkspace"),
|
|
25656
|
+
tabs: [
|
|
25657
|
+
{ id: "chat", name: t4("app.tabChat"), glyph: "\u25C6", panel: () => html5`<${ChatPanel} />` },
|
|
25658
|
+
{ id: "plans", name: t4("app.tabPlans"), glyph: "\u229E", panel: () => html5`<${PlansPanel} />` },
|
|
25659
|
+
{ id: "sessions", name: t4("app.tabSessions"), glyph: "\u203A", panel: () => html5`<${SessionsPanel} />` }
|
|
25660
|
+
]
|
|
25661
|
+
},
|
|
25662
|
+
{
|
|
25663
|
+
label: t4("app.sectionObserve"),
|
|
25664
|
+
tabs: [
|
|
25665
|
+
{ id: "overview", name: t4("app.tabOverview"), glyph: "\u25C8", panel: () => html5`<${OverviewPanel} />` },
|
|
25666
|
+
{ id: "usage", name: t4("app.tabUsage"), glyph: "$", panel: () => html5`<${UsagePanel} />` },
|
|
25667
|
+
{ id: "health", name: t4("app.tabSystem"), glyph: "+", panel: () => html5`<${SystemPanel} />` },
|
|
25668
|
+
{ id: "semantic", name: t4("app.tabSemantic"), glyph: "\u2248", panel: () => html5`<${SemanticPanel} />` }
|
|
25669
|
+
]
|
|
25670
|
+
},
|
|
25671
|
+
{
|
|
25672
|
+
label: t4("app.sectionConfigure"),
|
|
25673
|
+
tabs: [
|
|
25674
|
+
{ id: "tools", name: t4("app.tabTools"), glyph: "\u25A3", panel: () => html5`<${ToolsPanel} />` },
|
|
25675
|
+
{ id: "permissions", name: t4("app.tabPermissions"), glyph: "\u258E", panel: () => html5`<${PermissionsPanel} />` },
|
|
25676
|
+
{ id: "mcp", name: t4("app.tabMcp"), glyph: "M", panel: () => html5`<${McpPanel} />` },
|
|
25677
|
+
{ id: "skills", name: t4("app.tabSkills"), glyph: "S", panel: () => html5`<${SkillsPanel} />` },
|
|
25678
|
+
{ id: "memory", name: t4("app.tabMemory"), glyph: "\xB7", panel: () => html5`<${MemoryPanel} />` },
|
|
25679
|
+
{ id: "hooks", name: t4("app.tabHooks"), glyph: "H", panel: () => html5`<${HooksPanel} />` },
|
|
25680
|
+
{ id: "settings", name: t4("app.tabSettings"), glyph: "\u2318", panel: () => html5`<${SettingsPanel} />` }
|
|
25681
|
+
]
|
|
25682
|
+
}
|
|
25683
|
+
];
|
|
25684
|
+
}
|
|
24557
25685
|
function App() {
|
|
24558
|
-
|
|
25686
|
+
useLang();
|
|
25687
|
+
_2(() => {
|
|
25688
|
+
initLangFromServer();
|
|
25689
|
+
}, []);
|
|
25690
|
+
const [activeId, setActiveId] = p2(() => {
|
|
25691
|
+
try {
|
|
25692
|
+
return localStorage.getItem("rx.activeTab") ?? "chat";
|
|
25693
|
+
} catch {
|
|
25694
|
+
return "chat";
|
|
25695
|
+
}
|
|
25696
|
+
});
|
|
24559
25697
|
const [sidebarCollapsed, setSidebarCollapsed] = p2(() => {
|
|
24560
25698
|
try {
|
|
24561
25699
|
return localStorage.getItem("rx.sidebarCollapsed") === "1";
|
|
@@ -24569,7 +25707,18 @@ function App() {
|
|
|
24569
25707
|
} catch {
|
|
24570
25708
|
}
|
|
24571
25709
|
}, [sidebarCollapsed]);
|
|
24572
|
-
|
|
25710
|
+
_2(() => {
|
|
25711
|
+
try {
|
|
25712
|
+
localStorage.setItem("rx.activeTab", activeId);
|
|
25713
|
+
} catch {
|
|
25714
|
+
}
|
|
25715
|
+
}, [activeId]);
|
|
25716
|
+
const TAB_SECTIONS = tabSections();
|
|
25717
|
+
const ALL_TABS = TAB_SECTIONS.flatMap((s3) => s3.tabs);
|
|
25718
|
+
const active = ALL_TABS.find((t5) => t5.id === activeId) ?? ALL_TABS[0];
|
|
25719
|
+
_2(() => {
|
|
25720
|
+
if (active.id !== activeId) setActiveId(active.id);
|
|
25721
|
+
}, [active.id, activeId]);
|
|
24573
25722
|
_2(() => {
|
|
24574
25723
|
const onNav = (ev) => {
|
|
24575
25724
|
const id = ev.detail?.tabId;
|
|
@@ -24628,7 +25777,7 @@ function App() {
|
|
|
24628
25777
|
</div>
|
|
24629
25778
|
<footer class="app-status">
|
|
24630
25779
|
<span class="grow"></span>
|
|
24631
|
-
<span class="item"
|
|
25780
|
+
<span class="item">${t4("app.footer")}</span>
|
|
24632
25781
|
</footer>
|
|
24633
25782
|
</div>
|
|
24634
25783
|
<${ToastStack} />
|