reasonix 0.31.0 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -7
- package/README.zh-CN.md +2 -6
- package/dashboard/dist/app.js +348 -80
- package/dashboard/dist/app.js.map +1 -1
- package/dist/cli/chat-EIFLHBZ6.js +39 -0
- package/dist/cli/chunk-2AWTGJ2C.js +110 -0
- package/dist/cli/chunk-2AWTGJ2C.js.map +1 -0
- package/dist/cli/chunk-3Q3C4W66.js +30 -0
- package/dist/cli/chunk-3Q3C4W66.js.map +1 -0
- package/dist/cli/chunk-4DCHFFEY.js +149 -0
- package/dist/cli/chunk-4DCHFFEY.js.map +1 -0
- package/dist/cli/chunk-5X7LZJDE.js +36 -0
- package/dist/cli/chunk-5X7LZJDE.js.map +1 -0
- package/dist/cli/chunk-6TMHAK5D.js +576 -0
- package/dist/cli/chunk-6TMHAK5D.js.map +1 -0
- package/dist/cli/chunk-APPB3ZPQ.js +43 -0
- package/dist/cli/chunk-APPB3ZPQ.js.map +1 -0
- package/dist/cli/chunk-BQNUJJN7.js +42 -0
- package/dist/cli/chunk-BQNUJJN7.js.map +1 -0
- package/dist/cli/chunk-CPOV2O73.js +39 -0
- package/dist/cli/chunk-CPOV2O73.js.map +1 -0
- package/dist/cli/chunk-D5DKXIP5.js +368 -0
- package/dist/cli/chunk-D5DKXIP5.js.map +1 -0
- package/dist/cli/chunk-DFP4YSVM.js +247 -0
- package/dist/cli/chunk-DFP4YSVM.js.map +1 -0
- package/dist/cli/chunk-DULSP7JH.js +410 -0
- package/dist/cli/chunk-DULSP7JH.js.map +1 -0
- package/dist/cli/chunk-FM57FNPJ.js +46 -0
- package/dist/cli/chunk-FM57FNPJ.js.map +1 -0
- package/dist/cli/chunk-FWGEHRB7.js +54 -0
- package/dist/cli/chunk-FWGEHRB7.js.map +1 -0
- package/dist/cli/chunk-FXGQ5NHE.js +513 -0
- package/dist/cli/chunk-FXGQ5NHE.js.map +1 -0
- package/dist/cli/chunk-G3XNWSFN.js +53 -0
- package/dist/cli/chunk-G3XNWSFN.js.map +1 -0
- package/dist/cli/chunk-I6YIAK6C.js +757 -0
- package/dist/cli/chunk-I6YIAK6C.js.map +1 -0
- package/dist/cli/chunk-J5VLP23S.js +94 -0
- package/dist/cli/chunk-J5VLP23S.js.map +1 -0
- package/dist/cli/chunk-KMWKGPFZ.js +303 -0
- package/dist/cli/chunk-KMWKGPFZ.js.map +1 -0
- package/dist/cli/chunk-LVQX5KGF.js +14934 -0
- package/dist/cli/chunk-LVQX5KGF.js.map +1 -0
- package/dist/cli/chunk-MHDNZXJJ.js +48 -0
- package/dist/cli/chunk-MHDNZXJJ.js.map +1 -0
- package/dist/cli/chunk-ORM6PK57.js +140 -0
- package/dist/cli/chunk-ORM6PK57.js.map +1 -0
- package/dist/cli/chunk-Q5GRLZJF.js +99 -0
- package/dist/cli/chunk-Q5GRLZJF.js.map +1 -0
- package/dist/cli/chunk-Q6YFXW7H.js +4986 -0
- package/dist/cli/chunk-Q6YFXW7H.js.map +1 -0
- package/dist/cli/chunk-QGE6AF76.js +1467 -0
- package/dist/cli/chunk-QGE6AF76.js.map +1 -0
- package/dist/cli/chunk-RFX7TYVV.js +28 -0
- package/dist/cli/chunk-RFX7TYVV.js.map +1 -0
- package/dist/cli/chunk-RZILUXUC.js +940 -0
- package/dist/cli/chunk-RZILUXUC.js.map +1 -0
- package/dist/cli/chunk-SDE5U32Z.js +535 -0
- package/dist/cli/chunk-SDE5U32Z.js.map +1 -0
- package/dist/cli/chunk-SOZE7V7V.js +340 -0
- package/dist/cli/chunk-SOZE7V7V.js.map +1 -0
- package/dist/cli/chunk-U3V2ZQ5J.js +479 -0
- package/dist/cli/chunk-U3V2ZQ5J.js.map +1 -0
- package/dist/cli/chunk-W4LDFAZ6.js +1544 -0
- package/dist/cli/chunk-W4LDFAZ6.js.map +1 -0
- package/dist/cli/chunk-WBDE4IRI.js +208 -0
- package/dist/cli/chunk-WBDE4IRI.js.map +1 -0
- package/dist/cli/chunk-XHQIK7B6.js +189 -0
- package/dist/cli/chunk-XHQIK7B6.js.map +1 -0
- package/dist/cli/chunk-XJLZ4HKU.js +307 -0
- package/dist/cli/chunk-XJLZ4HKU.js.map +1 -0
- package/dist/cli/chunk-ZPTSJGX5.js +88 -0
- package/dist/cli/chunk-ZPTSJGX5.js.map +1 -0
- package/dist/cli/chunk-ZTLZO42A.js +231 -0
- package/dist/cli/chunk-ZTLZO42A.js.map +1 -0
- package/dist/cli/code-F4KJOE3K.js +151 -0
- package/dist/cli/code-F4KJOE3K.js.map +1 -0
- package/dist/cli/commands-JWT2MWVH.js +352 -0
- package/dist/cli/commands-JWT2MWVH.js.map +1 -0
- package/dist/cli/commit-RPZBOZS2.js +288 -0
- package/dist/cli/commit-RPZBOZS2.js.map +1 -0
- package/dist/cli/diff-NTEHCSDW.js +145 -0
- package/dist/cli/diff-NTEHCSDW.js.map +1 -0
- package/dist/cli/doctor-3TGB2NZN.js +19 -0
- package/dist/cli/doctor-3TGB2NZN.js.map +1 -0
- package/dist/cli/events-P27CX7LN.js +338 -0
- package/dist/cli/events-P27CX7LN.js.map +1 -0
- package/dist/cli/index.js +83 -34028
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-ARTNQ24O.js +266 -0
- package/dist/cli/mcp-ARTNQ24O.js.map +1 -0
- package/dist/cli/mcp-browse-HLO2ENDL.js +163 -0
- package/dist/cli/mcp-browse-HLO2ENDL.js.map +1 -0
- package/dist/cli/mcp-inspect-T2HBR22P.js +103 -0
- package/dist/cli/mcp-inspect-T2HBR22P.js.map +1 -0
- package/dist/cli/{prompt-XHICFAYN.js → prompt-V47QKSAR.js} +3 -2
- package/dist/cli/prompt-V47QKSAR.js.map +1 -0
- package/dist/cli/prune-sessions-ERL6B4G5.js +42 -0
- package/dist/cli/prune-sessions-ERL6B4G5.js.map +1 -0
- package/dist/cli/replay-TMJASRC4.js +273 -0
- package/dist/cli/replay-TMJASRC4.js.map +1 -0
- package/dist/cli/run-JMEOTQCG.js +215 -0
- package/dist/cli/run-JMEOTQCG.js.map +1 -0
- package/dist/cli/server-SYC3OVOP.js +2967 -0
- package/dist/cli/server-SYC3OVOP.js.map +1 -0
- package/dist/cli/sessions-MOJAALJI.js +102 -0
- package/dist/cli/sessions-MOJAALJI.js.map +1 -0
- package/dist/cli/setup-CCJZAWTY.js +404 -0
- package/dist/cli/setup-CCJZAWTY.js.map +1 -0
- package/dist/cli/stats-5RJCATCE.js +12 -0
- package/dist/cli/stats-5RJCATCE.js.map +1 -0
- package/dist/cli/update-4TJWRUIN.js +90 -0
- package/dist/cli/update-4TJWRUIN.js.map +1 -0
- package/dist/cli/version-3MYFE4G6.js +29 -0
- package/dist/cli/version-3MYFE4G6.js.map +1 -0
- package/dist/index.d.ts +49 -96
- package/dist/index.js +567 -759
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/chunk-VWFJNLIK.js +0 -1031
- package/dist/cli/chunk-VWFJNLIK.js.map +0 -1
- /package/dist/cli/{prompt-XHICFAYN.js.map → chat-EIFLHBZ6.js.map} +0 -0
package/dashboard/dist/app.js
CHANGED
|
@@ -19637,16 +19637,34 @@ var en = {
|
|
|
19637
19637
|
pullModel: "Pull {model}",
|
|
19638
19638
|
indexStatus: "index status",
|
|
19639
19639
|
builtStatus: "\u25CF built",
|
|
19640
|
+
incompatibleStatus: "\u25CF incompatible",
|
|
19640
19641
|
chunks: "chunks",
|
|
19641
19642
|
files: "files",
|
|
19642
19643
|
dim: "dim",
|
|
19643
19644
|
size: "size",
|
|
19644
19645
|
lastBuild: "last build",
|
|
19646
|
+
builtWith: "built with",
|
|
19647
|
+
currentTarget: "current target",
|
|
19648
|
+
incompatibleHint: "This on-disk index was built for a different provider or model. Run Rebuild to replace it.",
|
|
19645
19649
|
runIndexHint: "Run an index to enable semantic_search.",
|
|
19646
19650
|
reIndex: "Re-index",
|
|
19647
19651
|
build: "Build",
|
|
19648
19652
|
rebuild: "Rebuild",
|
|
19649
19653
|
stop: "Stop",
|
|
19654
|
+
provider: "provider",
|
|
19655
|
+
providerType: "service type",
|
|
19656
|
+
openaiCompat: "openai-compatible",
|
|
19657
|
+
apiUrl: "API URL",
|
|
19658
|
+
apiKey: "API key",
|
|
19659
|
+
apiKeyStoredNote: "API key is stored in ~/.reasonix/config.json \u2014 do not share that file.",
|
|
19660
|
+
customRequestBody: "custom request body",
|
|
19661
|
+
invalidCustomRequestBody: "Custom request body must be valid JSON: {error}",
|
|
19662
|
+
customRequestBodyMustBeObject: "Custom request body must be a JSON object.",
|
|
19663
|
+
saveBeforeIndex: "Save semantic settings before starting an index.",
|
|
19664
|
+
extraBody: "extra body",
|
|
19665
|
+
keepExistingKey: "leave blank to keep existing key",
|
|
19666
|
+
remoteProvider: "Remote embedding provider",
|
|
19667
|
+
remoteProviderDesc: "Configure the full OpenAI-compatible embeddings URL here. Reasonix will send requests exactly to the URL you provide.",
|
|
19650
19668
|
ollama: "ollama",
|
|
19651
19669
|
binary: "binary",
|
|
19652
19670
|
found: "found",
|
|
@@ -19674,11 +19692,14 @@ var en = {
|
|
|
19674
19692
|
nothingSkipped: "nothing skipped \u2014 all walked files would be indexed.",
|
|
19675
19693
|
firstIncluded: "first {count} included file(s)",
|
|
19676
19694
|
job: "Job",
|
|
19695
|
+
phaseSetup: "preparing",
|
|
19677
19696
|
phaseScan: "scanning files",
|
|
19678
19697
|
phaseEmbed: "embedding chunks",
|
|
19679
19698
|
phaseWrite: "writing index",
|
|
19680
19699
|
phaseDone: "done",
|
|
19681
19700
|
phaseError: "error",
|
|
19701
|
+
phaseCancelled: "cancelled",
|
|
19702
|
+
setupFailed: "setup failed",
|
|
19682
19703
|
stopping: "stopping",
|
|
19683
19704
|
scanned: "scanned {count}",
|
|
19684
19705
|
changed: "changed {count}",
|
|
@@ -20190,16 +20211,33 @@ var zhCN = {
|
|
|
20190
20211
|
pullModel: "\u62C9\u53D6 {model}",
|
|
20191
20212
|
indexStatus: "\u7D22\u5F15\u72B6\u6001",
|
|
20192
20213
|
builtStatus: "\u25CF \u5DF2\u6784\u5EFA",
|
|
20214
|
+
incompatibleStatus: "\u25CF \u4E0D\u517C\u5BB9",
|
|
20193
20215
|
chunks: "\u5206\u5757",
|
|
20194
20216
|
files: "\u6587\u4EF6",
|
|
20195
20217
|
dim: "\u7EF4\u5EA6",
|
|
20196
20218
|
size: "\u5927\u5C0F",
|
|
20197
20219
|
lastBuild: "\u4E0A\u6B21\u6784\u5EFA",
|
|
20220
|
+
builtWith: "\u6784\u5EFA\u6765\u6E90",
|
|
20221
|
+
currentTarget: "\u5F53\u524D\u76EE\u6807",
|
|
20222
|
+
incompatibleHint: "\u78C1\u76D8\u4E0A\u7684\u8FD9\u4E2A\u7D22\u5F15\u662F\u4E3A\u4E0D\u540C\u7684 provider \u6216 model \u6784\u5EFA\u7684\u3002\u8FD0\u884C\u201C\u5B8C\u5168\u91CD\u5EFA\u201D\u5373\u53EF\u66FF\u6362\u3002",
|
|
20198
20223
|
runIndexHint: "\u8FD0\u884C\u7D22\u5F15\u4EE5\u542F\u7528 semantic_search\u3002",
|
|
20199
20224
|
reIndex: "\u91CD\u5EFA\u7D22\u5F15",
|
|
20200
20225
|
build: "\u6784\u5EFA",
|
|
20201
20226
|
rebuild: "\u5B8C\u5168\u91CD\u5EFA",
|
|
20202
20227
|
stop: "\u505C\u6B62",
|
|
20228
|
+
provider: "\u63D0\u4F9B\u65B9",
|
|
20229
|
+
providerType: "\u670D\u52A1\u7C7B\u578B",
|
|
20230
|
+
openaiCompat: "OpenAI-Compatible",
|
|
20231
|
+
apiUrl: "API URL",
|
|
20232
|
+
apiKey: "API Key",
|
|
20233
|
+
customRequestBody: "\u81EA\u5B9A\u4E49\u8BF7\u6C42\u4F53",
|
|
20234
|
+
invalidCustomRequestBody: "\u81EA\u5B9A\u4E49\u8BF7\u6C42\u4F53\u5FC5\u987B\u662F\u5408\u6CD5 JSON\uFF1A{error}",
|
|
20235
|
+
customRequestBodyMustBeObject: "\u81EA\u5B9A\u4E49\u8BF7\u6C42\u4F53\u5FC5\u987B\u662F JSON \u5BF9\u8C61\u3002",
|
|
20236
|
+
saveBeforeIndex: "\u8BF7\u5148\u4FDD\u5B58\u8BED\u4E49\u8BBE\u7F6E\uFF0C\u518D\u542F\u52A8\u7D22\u5F15\u3002",
|
|
20237
|
+
extraBody: "\u6269\u5C55\u8BF7\u6C42\u4F53",
|
|
20238
|
+
keepExistingKey: "\u7559\u7A7A\u5219\u4FDD\u7559\u73B0\u6709 Key",
|
|
20239
|
+
remoteProvider: "\u8FDC\u7A0B\u5411\u91CF\u670D\u52A1",
|
|
20240
|
+
remoteProviderDesc: "\u5728\u8FD9\u91CC\u914D\u7F6E OpenAI-Compatible embeddings \u7684\u5B8C\u6574 URL\u3002Reasonix \u4F1A\u4E25\u683C\u4F7F\u7528\u4F60\u63D0\u4F9B\u7684 URL \u53D1\u8D77\u8BF7\u6C42\u3002",
|
|
20203
20241
|
ollama: "Ollama",
|
|
20204
20242
|
binary: "\u4E8C\u8FDB\u5236",
|
|
20205
20243
|
found: "\u5DF2\u627E\u5230",
|
|
@@ -20227,11 +20265,14 @@ var zhCN = {
|
|
|
20227
20265
|
nothingSkipped: "\u65E0\u8DF3\u8FC7 \u2014 \u6240\u6709\u904D\u5386\u7684\u6587\u4EF6\u90FD\u5C06\u88AB\u7D22\u5F15\u3002",
|
|
20228
20266
|
firstIncluded: "\u524D {count} \u4E2A\u5305\u542B\u7684\u6587\u4EF6",
|
|
20229
20267
|
job: "\u4EFB\u52A1",
|
|
20268
|
+
phaseSetup: "\u521D\u59CB\u5316\u4E2D",
|
|
20230
20269
|
phaseScan: "\u626B\u63CF\u6587\u4EF6",
|
|
20231
20270
|
phaseEmbed: "\u5D4C\u5165\u5206\u5757",
|
|
20232
20271
|
phaseWrite: "\u5199\u5165\u7D22\u5F15",
|
|
20233
20272
|
phaseDone: "\u5B8C\u6210",
|
|
20234
20273
|
phaseError: "\u9519\u8BEF",
|
|
20274
|
+
phaseCancelled: "\u5DF2\u505C\u6B62",
|
|
20275
|
+
setupFailed: "\u521D\u59CB\u5316\u5931\u8D25",
|
|
20235
20276
|
stopping: "\u505C\u6B62\u4E2D",
|
|
20236
20277
|
scanned: "\u5DF2\u626B\u63CF {count}",
|
|
20237
20278
|
changed: "\u5DF2\u53D8\u66F4 {count}",
|
|
@@ -25387,13 +25428,20 @@ function PlansPanel() {
|
|
|
25387
25428
|
function SemanticPanel() {
|
|
25388
25429
|
useLang();
|
|
25389
25430
|
const [data, setData] = d2(null);
|
|
25431
|
+
const [draft, setDraft] = d2(null);
|
|
25432
|
+
const [draftDirty, setDraftDirty] = d2(false);
|
|
25433
|
+
const draftDirtyRef = A2(false);
|
|
25390
25434
|
const [error, setError] = d2(null);
|
|
25391
25435
|
const [busy, setBusy] = d2(false);
|
|
25392
25436
|
const [info, setInfo] = d2(null);
|
|
25393
25437
|
const load = q2(async () => {
|
|
25394
25438
|
try {
|
|
25395
|
-
const
|
|
25396
|
-
|
|
25439
|
+
const [semantic, config] = await Promise.all([
|
|
25440
|
+
api("/semantic"),
|
|
25441
|
+
api("/semantic/config")
|
|
25442
|
+
]);
|
|
25443
|
+
setData(semantic);
|
|
25444
|
+
setDraft((current) => current && draftDirtyRef.current ? current : toConfigDraft(config));
|
|
25397
25445
|
} catch (err) {
|
|
25398
25446
|
setError(err.message);
|
|
25399
25447
|
}
|
|
@@ -25401,7 +25449,7 @@ function SemanticPanel() {
|
|
|
25401
25449
|
y2(() => {
|
|
25402
25450
|
load();
|
|
25403
25451
|
const phase2 = data?.job?.phase;
|
|
25404
|
-
const running2 = phase2
|
|
25452
|
+
const running2 = isActiveSemanticPhase(phase2);
|
|
25405
25453
|
const pulling2 = data?.pull?.status === "pulling";
|
|
25406
25454
|
const ms = running2 || pulling2 ? 1200 : 5e3;
|
|
25407
25455
|
const id = setInterval(load, ms);
|
|
@@ -25409,10 +25457,18 @@ function SemanticPanel() {
|
|
|
25409
25457
|
}, [load, data?.job?.phase, data?.pull?.status]);
|
|
25410
25458
|
const start = q2(
|
|
25411
25459
|
async (rebuild) => {
|
|
25460
|
+
if (!draft) return;
|
|
25412
25461
|
setBusy(true);
|
|
25413
25462
|
setError(null);
|
|
25414
25463
|
setInfo(null);
|
|
25415
25464
|
try {
|
|
25465
|
+
const validation = validateSemanticDraft(draft);
|
|
25466
|
+
if (draftDirty) {
|
|
25467
|
+
throw new Error(t4("semantic.saveBeforeIndex"));
|
|
25468
|
+
}
|
|
25469
|
+
if (validation.error) {
|
|
25470
|
+
throw new Error(validation.error);
|
|
25471
|
+
}
|
|
25416
25472
|
await api("/semantic/start", { method: "POST", body: { rebuild: !!rebuild } });
|
|
25417
25473
|
setInfo(rebuild ? t4("semantic.rebuildStarted") : t4("semantic.incrementalStarted"));
|
|
25418
25474
|
await load();
|
|
@@ -25422,7 +25478,7 @@ function SemanticPanel() {
|
|
|
25422
25478
|
setBusy(false);
|
|
25423
25479
|
}
|
|
25424
25480
|
},
|
|
25425
|
-
[load]
|
|
25481
|
+
[draft, draftDirty, load]
|
|
25426
25482
|
);
|
|
25427
25483
|
const stop = q2(async () => {
|
|
25428
25484
|
setBusy(true);
|
|
@@ -25442,10 +25498,11 @@ function SemanticPanel() {
|
|
|
25442
25498
|
setError(null);
|
|
25443
25499
|
setInfo(t4("semantic.startingDaemon"));
|
|
25444
25500
|
try {
|
|
25445
|
-
const r3 = await api("/semantic/ollama/start", {
|
|
25446
|
-
|
|
25447
|
-
|
|
25448
|
-
);
|
|
25501
|
+
const r3 = await api("/semantic/ollama/start", {
|
|
25502
|
+
method: "POST",
|
|
25503
|
+
body: {}
|
|
25504
|
+
});
|
|
25505
|
+
setInfo(r3.ready ? t4("semantic.daemonUp") : t4("semantic.daemonTimeout"));
|
|
25449
25506
|
await load();
|
|
25450
25507
|
} catch (err) {
|
|
25451
25508
|
setError(err.message);
|
|
@@ -25469,10 +25526,44 @@ function SemanticPanel() {
|
|
|
25469
25526
|
},
|
|
25470
25527
|
[load]
|
|
25471
25528
|
);
|
|
25472
|
-
|
|
25529
|
+
const saveProviderConfig = q2(async () => {
|
|
25530
|
+
if (!draft) return;
|
|
25531
|
+
setBusy(true);
|
|
25532
|
+
setError(null);
|
|
25533
|
+
setInfo(null);
|
|
25534
|
+
try {
|
|
25535
|
+
const extraBody = semanticValidation.extraBody;
|
|
25536
|
+
await api("/semantic/config", {
|
|
25537
|
+
method: "POST",
|
|
25538
|
+
body: {
|
|
25539
|
+
provider: draft.provider,
|
|
25540
|
+
ollama: {
|
|
25541
|
+
baseUrl: draft.ollama.baseUrl,
|
|
25542
|
+
model: draft.ollama.model
|
|
25543
|
+
},
|
|
25544
|
+
openaiCompat: {
|
|
25545
|
+
baseUrl: draft.openaiCompat.baseUrl,
|
|
25546
|
+
apiKey: draft.openaiCompat.apiKey,
|
|
25547
|
+
model: draft.openaiCompat.model,
|
|
25548
|
+
extraBody
|
|
25549
|
+
}
|
|
25550
|
+
}
|
|
25551
|
+
});
|
|
25552
|
+
setDraftDirty(false);
|
|
25553
|
+
draftDirtyRef.current = false;
|
|
25554
|
+
setInfo(t4("semantic.savedConfig", { count: 1 }));
|
|
25555
|
+
await load();
|
|
25556
|
+
} catch (err) {
|
|
25557
|
+
setError(err.message);
|
|
25558
|
+
} finally {
|
|
25559
|
+
setBusy(false);
|
|
25560
|
+
}
|
|
25561
|
+
}, [draft, load]);
|
|
25562
|
+
if (!data && !error) {
|
|
25473
25563
|
return html4`<div class="card" style="color:var(--fg-3)">${t4("common.loading")}</div>`;
|
|
25564
|
+
}
|
|
25474
25565
|
if (error && !data) return html4`<div class="card accent-err">${error}</div>`;
|
|
25475
|
-
if (!data) return null;
|
|
25566
|
+
if (!data || !draft) return null;
|
|
25476
25567
|
if (!data.attached) {
|
|
25477
25568
|
return html4`
|
|
25478
25569
|
<div class="card" style="color:var(--fg-3)">
|
|
@@ -25483,35 +25574,168 @@ function SemanticPanel() {
|
|
|
25483
25574
|
}
|
|
25484
25575
|
const job = data.job;
|
|
25485
25576
|
const phase = job?.phase;
|
|
25486
|
-
const running = phase
|
|
25577
|
+
const running = isActiveSemanticPhase(phase);
|
|
25487
25578
|
const pull = data.pull;
|
|
25488
25579
|
const pulling = pull?.status === "pulling";
|
|
25489
|
-
const
|
|
25490
|
-
const
|
|
25491
|
-
const
|
|
25492
|
-
const
|
|
25493
|
-
const
|
|
25494
|
-
const
|
|
25495
|
-
const
|
|
25580
|
+
const provider = data.providerStatus?.kind ?? draft.provider;
|
|
25581
|
+
const ready = data.providerStatus?.ready === true;
|
|
25582
|
+
const isOllama = provider === "ollama";
|
|
25583
|
+
const ollama = data.providerStatus?.kind === "ollama" ? data.providerStatus : null;
|
|
25584
|
+
const remote = data.providerStatus?.kind === "openai-compat" ? data.providerStatus : null;
|
|
25585
|
+
const binaryFound = ollama?.binaryFound === true;
|
|
25586
|
+
const daemonRunning = ollama?.daemonRunning === true;
|
|
25587
|
+
const modelPulled = ollama?.modelPulled === true;
|
|
25588
|
+
const modelName = isOllama ? ollama?.modelName ?? draft.ollama.model ?? "nomic-embed-text" : draft.openaiCompat.model;
|
|
25496
25589
|
const sectionH3 = (text) => html4`
|
|
25497
25590
|
<h3 style="margin:18px 0 8px;font-family:var(--font-mono);font-size:11px;color:var(--fg-3);text-transform:uppercase;letter-spacing:.1em">${text}</h3>
|
|
25498
25591
|
`;
|
|
25499
25592
|
const idx = data.index;
|
|
25593
|
+
const indexReady = idx?.exists === true && idx.compatible !== false;
|
|
25594
|
+
const indexMismatch = idx?.exists === true && idx.compatible === false;
|
|
25595
|
+
const semanticValidation = validateSemanticDraft(draft);
|
|
25596
|
+
const semanticDraftBlocked = draftDirty || semanticValidation.error !== null;
|
|
25500
25597
|
return html4`
|
|
25501
25598
|
<div style="display:grid;grid-template-columns:minmax(0,1fr) 280px;gap:14px;align-items:start">
|
|
25502
25599
|
<div style="display:flex;flex-direction:column;gap:10px;min-width:0">
|
|
25503
25600
|
<div class="chips">
|
|
25504
|
-
<span class=${`chip-f static ${
|
|
25505
|
-
${
|
|
25601
|
+
<span class=${`chip-f static ${indexReady ? "active" : ""}`}>
|
|
25602
|
+
${indexReady ? t4("semantic.indexBuilt") : t4("semantic.noIndex")}
|
|
25506
25603
|
</span>
|
|
25507
25604
|
${ready ? html4`<span class="chip-f static" style="border-color:var(--c-ok);color:var(--c-ok)">${t4("semantic.ready")}</span>` : html4`<span class="chip-f static" style="border-color:var(--c-warn);color:var(--c-warn)">${t4("semantic.setupNeeded")}</span>`}
|
|
25508
25605
|
</div>
|
|
25509
|
-
${info ? html4`<div><span class="pill info">${info}</span></div>` : null}
|
|
25510
25606
|
${error ? html4`<div class="card accent-err">${error}</div>` : null}
|
|
25511
25607
|
|
|
25512
|
-
|
|
25608
|
+
<div class="card">
|
|
25609
|
+
<div class="card-h"><span class="title">${t4("semantic.provider")}</span></div>
|
|
25610
|
+
<div class="form-row">
|
|
25611
|
+
<span class="lbl">${t4("semantic.providerType")}</span>
|
|
25612
|
+
<select
|
|
25613
|
+
class="input mono"
|
|
25614
|
+
value=${draft.provider}
|
|
25615
|
+
onInput=${(e3) => {
|
|
25616
|
+
draftDirtyRef.current = true;
|
|
25617
|
+
setDraftDirty(true);
|
|
25618
|
+
setDraft({
|
|
25619
|
+
...draft,
|
|
25620
|
+
provider: e3.target.value
|
|
25621
|
+
});
|
|
25622
|
+
}}
|
|
25623
|
+
>
|
|
25624
|
+
<option value="ollama">Ollama</option>
|
|
25625
|
+
<option value="openai-compat">OpenAI-Compatible</option>
|
|
25626
|
+
</select>
|
|
25627
|
+
</div>
|
|
25628
|
+
${draft.provider === "ollama" ? html4`
|
|
25629
|
+
<div class="form-row">
|
|
25630
|
+
<span class="lbl">${t4("semantic.model")}</span>
|
|
25631
|
+
<input
|
|
25632
|
+
class="input mono"
|
|
25633
|
+
type="text"
|
|
25634
|
+
value=${draft.ollama.model}
|
|
25635
|
+
onInput=${(e3) => {
|
|
25636
|
+
draftDirtyRef.current = true;
|
|
25637
|
+
setDraftDirty(true);
|
|
25638
|
+
setDraft({
|
|
25639
|
+
...draft,
|
|
25640
|
+
ollama: { ...draft.ollama, model: e3.target.value }
|
|
25641
|
+
});
|
|
25642
|
+
}}
|
|
25643
|
+
/>
|
|
25644
|
+
</div>
|
|
25645
|
+
` : html4`
|
|
25646
|
+
<div class="form-row">
|
|
25647
|
+
<span class="lbl">${t4("semantic.apiUrl")}</span>
|
|
25648
|
+
<input
|
|
25649
|
+
class="input mono"
|
|
25650
|
+
type="text"
|
|
25651
|
+
placeholder="https://api.openai.com/v1/embeddings"
|
|
25652
|
+
value=${draft.openaiCompat.baseUrl}
|
|
25653
|
+
onInput=${(e3) => {
|
|
25654
|
+
draftDirtyRef.current = true;
|
|
25655
|
+
setDraftDirty(true);
|
|
25656
|
+
setDraft({
|
|
25657
|
+
...draft,
|
|
25658
|
+
openaiCompat: {
|
|
25659
|
+
...draft.openaiCompat,
|
|
25660
|
+
baseUrl: e3.target.value
|
|
25661
|
+
}
|
|
25662
|
+
});
|
|
25663
|
+
}}
|
|
25664
|
+
/>
|
|
25665
|
+
</div>
|
|
25666
|
+
<div class="form-row">
|
|
25667
|
+
<span class="lbl">${t4("semantic.apiKey")}</span>
|
|
25668
|
+
<input
|
|
25669
|
+
class="input mono"
|
|
25670
|
+
type="password"
|
|
25671
|
+
placeholder=${draft.openaiCompat.apiKeySet ? t4("semantic.keepExistingKey") : "sk-..."}
|
|
25672
|
+
value=${draft.openaiCompat.apiKey}
|
|
25673
|
+
onInput=${(e3) => {
|
|
25674
|
+
draftDirtyRef.current = true;
|
|
25675
|
+
setDraftDirty(true);
|
|
25676
|
+
setDraft({
|
|
25677
|
+
...draft,
|
|
25678
|
+
openaiCompat: {
|
|
25679
|
+
...draft.openaiCompat,
|
|
25680
|
+
apiKey: e3.target.value
|
|
25681
|
+
}
|
|
25682
|
+
});
|
|
25683
|
+
}}
|
|
25684
|
+
/>
|
|
25685
|
+
<div style="color:var(--fg-3);font-size:12px">${t4("semantic.apiKeyStoredNote")}</div>
|
|
25686
|
+
</div>
|
|
25687
|
+
<div class="form-row">
|
|
25688
|
+
<span class="lbl">${t4("semantic.model")}</span>
|
|
25689
|
+
<input
|
|
25690
|
+
class="input mono"
|
|
25691
|
+
type="text"
|
|
25692
|
+
value=${draft.openaiCompat.model}
|
|
25693
|
+
onInput=${(e3) => {
|
|
25694
|
+
draftDirtyRef.current = true;
|
|
25695
|
+
setDraftDirty(true);
|
|
25696
|
+
setDraft({
|
|
25697
|
+
...draft,
|
|
25698
|
+
openaiCompat: {
|
|
25699
|
+
...draft.openaiCompat,
|
|
25700
|
+
model: e3.target.value
|
|
25701
|
+
}
|
|
25702
|
+
});
|
|
25703
|
+
}}
|
|
25704
|
+
/>
|
|
25705
|
+
</div>
|
|
25706
|
+
<details style="margin-top:10px">
|
|
25707
|
+
<summary style="cursor:pointer;color:var(--fg-2);font-size:12px">${t4("semantic.customRequestBody")}</summary>
|
|
25708
|
+
<div class="form-row" style="margin-top:10px">
|
|
25709
|
+
<span class="lbl">${t4("semantic.customRequestBody")}</span>
|
|
25710
|
+
<textarea
|
|
25711
|
+
class="input mono"
|
|
25712
|
+
rows="6"
|
|
25713
|
+
value=${draft.openaiCompat.extraBodyText}
|
|
25714
|
+
onInput=${(e3) => {
|
|
25715
|
+
draftDirtyRef.current = true;
|
|
25716
|
+
setDraftDirty(true);
|
|
25717
|
+
setDraft({
|
|
25718
|
+
...draft,
|
|
25719
|
+
openaiCompat: {
|
|
25720
|
+
...draft.openaiCompat,
|
|
25721
|
+
extraBodyText: e3.target.value
|
|
25722
|
+
}
|
|
25723
|
+
});
|
|
25724
|
+
}}
|
|
25725
|
+
></textarea>
|
|
25726
|
+
</div>
|
|
25727
|
+
</details>
|
|
25728
|
+
${semanticValidation.error ? html4`<div style="color:var(--c-err);font-size:12px;margin-top:-2px">${semanticValidation.error}</div>` : null}
|
|
25729
|
+
`}
|
|
25730
|
+
<div style="display:flex;gap:6px;margin-top:10px">
|
|
25731
|
+
<button class="btn primary" disabled=${busy || semanticValidation.error !== null} onClick=${saveProviderConfig}>${t4("common.save")}</button>
|
|
25732
|
+
</div>
|
|
25733
|
+
</div>
|
|
25734
|
+
${info ? html4`<div><span class="pill info">${info}</span></div>` : null}
|
|
25735
|
+
|
|
25736
|
+
${indexReady ? html4`<${SemanticSearchSection} />` : null}
|
|
25513
25737
|
|
|
25514
|
-
${!binaryFound ? html4`
|
|
25738
|
+
${isOllama && !binaryFound ? html4`
|
|
25515
25739
|
<div class="card">
|
|
25516
25740
|
<div class="card-h"><span class="title">${t4("semantic.installOllama")}</span></div>
|
|
25517
25741
|
<div class="card-b" style="font-size:13px">
|
|
@@ -25524,7 +25748,7 @@ function SemanticPanel() {
|
|
|
25524
25748
|
</div>
|
|
25525
25749
|
</div>
|
|
25526
25750
|
` : null}
|
|
25527
|
-
${binaryFound && !daemonRunning ? html4`
|
|
25751
|
+
${isOllama && binaryFound && !daemonRunning ? html4`
|
|
25528
25752
|
<div class="card">
|
|
25529
25753
|
<div class="card-h"><span class="title">${t4("semantic.daemon")}</span></div>
|
|
25530
25754
|
<div class="card-b" style="font-size:13px">
|
|
@@ -25536,7 +25760,7 @@ function SemanticPanel() {
|
|
|
25536
25760
|
</div>
|
|
25537
25761
|
</div>
|
|
25538
25762
|
` : null}
|
|
25539
|
-
${daemonRunning && !modelPulled ? html4`
|
|
25763
|
+
${isOllama && daemonRunning && !modelPulled ? html4`
|
|
25540
25764
|
<div class="card">
|
|
25541
25765
|
<div class="card-h"><span class="title">${t4("semantic.model")}</span></div>
|
|
25542
25766
|
<div class="card-b" style="font-size:13px">
|
|
@@ -25556,6 +25780,14 @@ function SemanticPanel() {
|
|
|
25556
25780
|
</div>
|
|
25557
25781
|
</div>
|
|
25558
25782
|
` : null}
|
|
25783
|
+
${!isOllama ? html4`
|
|
25784
|
+
<div class="card">
|
|
25785
|
+
<div class="card-h"><span class="title">${t4("semantic.remoteProvider")}</span></div>
|
|
25786
|
+
<div class="card-b" style="font-size:13px;color:var(--fg-2)">
|
|
25787
|
+
${t4("semantic.remoteProviderDesc")}
|
|
25788
|
+
</div>
|
|
25789
|
+
</div>
|
|
25790
|
+
` : null}
|
|
25559
25791
|
|
|
25560
25792
|
${job ? html4`
|
|
25561
25793
|
${sectionH3(t4("semantic.job"))}
|
|
@@ -25568,42 +25800,42 @@ function SemanticPanel() {
|
|
|
25568
25800
|
<div class="card-h">
|
|
25569
25801
|
<span class="title">${t4("semantic.indexStatus")}</span>
|
|
25570
25802
|
<span class="meta">
|
|
25571
|
-
${idx?.exists ? html4`<span class="pill ok">${t4("semantic.builtStatus")}</span>` : html4`<span class="pill">${t4("system.none")}</span>`}
|
|
25803
|
+
${idx?.exists ? idx.compatible === false ? html4`<span class="pill warn">${t4("semantic.incompatibleStatus")}</span>` : html4`<span class="pill ok">${t4("semantic.builtStatus")}</span>` : html4`<span class="pill">${t4("system.none")}</span>`}
|
|
25572
25804
|
</span>
|
|
25573
25805
|
</div>
|
|
25574
25806
|
${idx?.exists ? html4`
|
|
25807
|
+
<div class="rail-kv"><span class="k">${t4("semantic.provider")}</span><span class="v">${idx.builtWith?.provider ?? idx.provider ?? provider}</span></div>
|
|
25575
25808
|
<div class="rail-kv"><span class="k">${t4("semantic.chunks")}</span><span class="v">${fmtNum(idx.chunks)}</span></div>
|
|
25576
25809
|
<div class="rail-kv"><span class="k">${t4("semantic.files")}</span><span class="v">${fmtNum(idx.files)}</span></div>
|
|
25577
|
-
<div class="rail-kv"><span class="k">${t4("semantic.model")}</span><span class="v" style="font-size:11px">${idx.model ?? modelName}</span></div>
|
|
25810
|
+
<div class="rail-kv"><span class="k">${t4("semantic.model")}</span><span class="v" style="font-size:11px">${idx.builtWith?.model ?? idx.model ?? modelName}</span></div>
|
|
25578
25811
|
<div class="rail-kv"><span class="k">${t4("semantic.dim")}</span><span class="v">${fmtNum(idx.dim)}</span></div>
|
|
25579
25812
|
<div class="rail-kv"><span class="k">${t4("semantic.size")}</span><span class="v">${fmtBytes(idx.sizeBytes)}</span></div>
|
|
25580
25813
|
<div class="rail-kv"><span class="k">${t4("semantic.lastBuild")}</span><span class="v">${fmtRelativeTime(idx.lastBuiltMs ?? null)}</span></div>
|
|
25581
|
-
|
|
25582
|
-
|
|
25583
|
-
|
|
25584
|
-
|
|
25585
|
-
|
|
25814
|
+
${idx.compatible === false ? html4`
|
|
25815
|
+
<div class="rail-kv"><span class="k">${t4("semantic.builtWith")}</span><span class="v" style="font-size:11px">${idx.builtWith?.provider} · ${idx.builtWith?.model}</span></div>
|
|
25816
|
+
<div class="rail-kv"><span class="k">${t4("semantic.currentTarget")}</span><span class="v" style="font-size:11px">${idx.current?.provider} · ${idx.current?.model}</span></div>
|
|
25817
|
+
<div style="color:var(--c-warn);font-size:12px;padding-top:8px">${t4("semantic.incompatibleHint")}</div>
|
|
25818
|
+
` : null}
|
|
25819
|
+
` : html4`<div style="color:var(--fg-3);font-size:12.5px;padding:6px 0">${t4("semantic.runIndexHint")}</div>`}
|
|
25586
25820
|
<div style="display:flex;gap:6px;margin-top:10px;flex-wrap:wrap">
|
|
25587
|
-
<button class="primary" disabled=${busy || running || !ready} onClick=${() => start(false)}>${
|
|
25588
|
-
${idx?.exists ? html4`<button disabled=${busy || running || !ready} onClick=${() => start(true)}>${t4("semantic.rebuild")}</button>` : null}
|
|
25821
|
+
<button class="primary" disabled=${busy || running || !ready || semanticDraftBlocked} onClick=${() => start(false)}>${indexReady ? t4("semantic.reIndex") : t4("semantic.build")}</button>
|
|
25822
|
+
${idx?.exists ? html4`<button disabled=${busy || running || !ready || semanticDraftBlocked} onClick=${() => start(true)}>${t4("semantic.rebuild")}</button>` : null}
|
|
25589
25823
|
${running ? html4`<button onClick=${stop} style="border-color:var(--c-err);color:var(--c-err)">${t4("semantic.stop")}</button>` : null}
|
|
25590
25824
|
</div>
|
|
25591
25825
|
</div>
|
|
25592
25826
|
|
|
25593
25827
|
<div class="card">
|
|
25594
|
-
<div class="card-h"><span class="title">${t4("semantic.ollama")}</span></div>
|
|
25595
|
-
|
|
25596
|
-
|
|
25597
|
-
|
|
25598
|
-
|
|
25599
|
-
|
|
25600
|
-
|
|
25601
|
-
|
|
25602
|
-
|
|
25603
|
-
|
|
25604
|
-
|
|
25605
|
-
<span class="v">${modelPulled ? html4`<span class="pill ok">${t4("semantic.pulled")}</span>` : html4`<span class="pill warn">${t4("semantic.missing")}</span>`}</span>
|
|
25606
|
-
</div>
|
|
25828
|
+
<div class="card-h"><span class="title">${isOllama ? t4("semantic.ollama") : t4("semantic.openaiCompat")}</span></div>
|
|
25829
|
+
${isOllama ? html4`
|
|
25830
|
+
<div class="rail-kv"><span class="k">${t4("semantic.binary")}</span><span class="v">${binaryFound ? html4`<span class="pill ok">${t4("semantic.found")}</span>` : html4`<span class="pill err">${t4("semantic.missing")}</span>`}</span></div>
|
|
25831
|
+
<div class="rail-kv"><span class="k">${t4("semantic.daemonStatus")}</span><span class="v">${daemonRunning ? html4`<span class="pill ok">${t4("semantic.up")}</span>` : html4`<span class="pill warn">${t4("semantic.down")}</span>`}</span></div>
|
|
25832
|
+
<div class="rail-kv"><span class="k">${t4("semantic.model")}</span><span class="v">${modelPulled ? html4`<span class="pill ok">${t4("semantic.pulled")}</span>` : html4`<span class="pill warn">${t4("semantic.missing")}</span>`}</span></div>
|
|
25833
|
+
` : html4`
|
|
25834
|
+
<div class="rail-kv"><span class="k">${t4("semantic.apiUrl")}</span><span class="v" style="font-size:11px;max-width:160px;overflow-wrap:anywhere;word-break:break-word;text-align:right">${remote?.baseUrl ?? draft.openaiCompat.baseUrl}</span></div>
|
|
25835
|
+
<div class="rail-kv"><span class="k">${t4("semantic.apiKey")}</span><span class="v">${remote?.apiKeySet ? html4`<span class="pill ok">${t4("semantic.found")}</span>` : html4`<span class="pill warn">${t4("semantic.missing")}</span>`}</span></div>
|
|
25836
|
+
<div class="rail-kv"><span class="k">${t4("semantic.model")}</span><span class="v" style="font-size:11px">${remote?.model ?? draft.openaiCompat.model}</span></div>
|
|
25837
|
+
<div class="rail-kv"><span class="k">${t4("semantic.extraBody")}</span><span class="v">${fmtNum(remote?.extraBodyKeys.length ?? 0)}</span></div>
|
|
25838
|
+
`}
|
|
25607
25839
|
</div>
|
|
25608
25840
|
|
|
25609
25841
|
<${SemanticExcludesCard} />
|
|
@@ -25611,6 +25843,44 @@ function SemanticPanel() {
|
|
|
25611
25843
|
</div>
|
|
25612
25844
|
`;
|
|
25613
25845
|
}
|
|
25846
|
+
function toConfigDraft(config) {
|
|
25847
|
+
return {
|
|
25848
|
+
provider: config.provider,
|
|
25849
|
+
ollama: {
|
|
25850
|
+
baseUrl: config.ollama.baseUrl,
|
|
25851
|
+
model: config.ollama.model
|
|
25852
|
+
},
|
|
25853
|
+
openaiCompat: {
|
|
25854
|
+
baseUrl: config.openaiCompat.baseUrl,
|
|
25855
|
+
apiKey: "",
|
|
25856
|
+
model: config.openaiCompat.model,
|
|
25857
|
+
extraBodyText: JSON.stringify(config.openaiCompat.extraBody ?? {}, null, 2),
|
|
25858
|
+
apiKeySet: config.openaiCompat.apiKeySet
|
|
25859
|
+
}
|
|
25860
|
+
};
|
|
25861
|
+
}
|
|
25862
|
+
function validateSemanticDraft(draft) {
|
|
25863
|
+
if (draft.provider !== "openai-compat") {
|
|
25864
|
+
return { extraBody: {}, error: null };
|
|
25865
|
+
}
|
|
25866
|
+
const raw = draft.openaiCompat.extraBodyText.trim();
|
|
25867
|
+
if (!raw) {
|
|
25868
|
+
return { extraBody: {}, error: null };
|
|
25869
|
+
}
|
|
25870
|
+
let parsed;
|
|
25871
|
+
try {
|
|
25872
|
+
parsed = JSON.parse(raw);
|
|
25873
|
+
} catch (err) {
|
|
25874
|
+
return {
|
|
25875
|
+
extraBody: {},
|
|
25876
|
+
error: t4("semantic.invalidCustomRequestBody", { error: err.message })
|
|
25877
|
+
};
|
|
25878
|
+
}
|
|
25879
|
+
if (!isPlainObject(parsed)) {
|
|
25880
|
+
return { extraBody: {}, error: t4("semantic.customRequestBodyMustBeObject") };
|
|
25881
|
+
}
|
|
25882
|
+
return { extraBody: parsed, error: null };
|
|
25883
|
+
}
|
|
25614
25884
|
function SemanticSearchSection() {
|
|
25615
25885
|
useLang();
|
|
25616
25886
|
const [query2, setQuery] = d2("");
|
|
@@ -25783,11 +26053,7 @@ function SemanticExcludesCard() {
|
|
|
25783
26053
|
<div class="card-h">
|
|
25784
26054
|
<span class="title">${t4("semantic.indexConfig")}</span>
|
|
25785
26055
|
<span class="meta">
|
|
25786
|
-
<a
|
|
25787
|
-
class="mono"
|
|
25788
|
-
style="color:var(--c-brand);text-decoration:none;font-size:11px;cursor:pointer"
|
|
25789
|
-
onClick=${reset}
|
|
25790
|
-
>${t4("semantic.reset")}</a>
|
|
26056
|
+
<a class="mono" style="color:var(--c-brand);text-decoration:none;font-size:11px;cursor:pointer" onClick=${reset}>${t4("semantic.reset")}</a>
|
|
25791
26057
|
</span>
|
|
25792
26058
|
</div>
|
|
25793
26059
|
${info ? html4`<div style="margin-bottom:8px"><span class="pill ok">${info}</span></div>` : null}
|
|
@@ -25819,11 +26085,7 @@ function SemanticExcludesCard() {
|
|
|
25819
26085
|
placeholder="**/*.test.ts"
|
|
25820
26086
|
/>
|
|
25821
26087
|
|
|
25822
|
-
<div
|
|
25823
|
-
class="checkbox-row"
|
|
25824
|
-
style="margin-top:8px;cursor:pointer"
|
|
25825
|
-
onClick=${() => setDraft({ ...draft, respectGitignore: !draft.respectGitignore })}
|
|
25826
|
-
>
|
|
26088
|
+
<div class="checkbox-row" style="margin-top:8px;cursor:pointer" onClick=${() => setDraft({ ...draft, respectGitignore: !draft.respectGitignore })}>
|
|
25827
26089
|
<span class=${`box ${draft.respectGitignore ? "on" : ""}`}>${draft.respectGitignore ? "\u2713" : ""}</span>
|
|
25828
26090
|
<span>${t4("semantic.respectGitignore")}</span>
|
|
25829
26091
|
</div>
|
|
@@ -25843,9 +26105,7 @@ function SemanticExcludesCard() {
|
|
|
25843
26105
|
</div>
|
|
25844
26106
|
|
|
25845
26107
|
<div style="display:flex;gap:6px;margin-top:10px">
|
|
25846
|
-
<button class="btn ghost" style="flex:1" disabled=${busy} onClick=${runPreview}>
|
|
25847
|
-
<span class="g">⊕</span><span>${t4("semantic.preview")}</span>
|
|
25848
|
-
</button>
|
|
26108
|
+
<button class="btn ghost" style="flex:1" disabled=${busy} onClick=${runPreview}><span class="g">⊕</span><span>${t4("semantic.preview")}</span></button>
|
|
25849
26109
|
<button class="btn primary" style="flex:1" disabled=${busy} onClick=${save}>${t4("common.save")}</button>
|
|
25850
26110
|
</div>
|
|
25851
26111
|
|
|
@@ -25870,19 +26130,17 @@ function ExcludesPreview({ preview }) {
|
|
|
25870
26130
|
].filter((k3) => (buckets[k3] || 0) > 0);
|
|
25871
26131
|
return html4`
|
|
25872
26132
|
<div class="excludes-preview">
|
|
25873
|
-
<div class="summary">
|
|
25874
|
-
${t4("semantic.previewSummary", { included: preview.filesIncluded, skipped: totalSkipped })}
|
|
25875
|
-
</div>
|
|
26133
|
+
<div class="summary">${t4("semantic.previewSummary", { included: preview.filesIncluded, skipped: totalSkipped })}</div>
|
|
25876
26134
|
${reasons.length === 0 ? html4`<div style="color:var(--fg-3)">${t4("semantic.nothingSkipped")}</div>` : reasons.map(
|
|
25877
26135
|
(r3) => html4`
|
|
25878
|
-
|
|
25879
|
-
|
|
25880
|
-
|
|
25881
|
-
|
|
25882
|
-
|
|
25883
|
-
|
|
25884
|
-
|
|
25885
|
-
|
|
26136
|
+
<details>
|
|
26137
|
+
<summary><strong>${r3}: ${buckets[r3]}</strong></summary>
|
|
26138
|
+
<ul>
|
|
26139
|
+
${(samples[r3] || []).map((p3) => html4`<li><code>${p3}</code></li>`)}
|
|
26140
|
+
${(buckets[r3] || 0) > (samples[r3] || []).length ? html4`<li style="color:var(--fg-3)">…${(buckets[r3] || 0) - (samples[r3] || []).length} more</li>` : null}
|
|
26141
|
+
</ul>
|
|
26142
|
+
</details>
|
|
26143
|
+
`
|
|
25886
26144
|
)}
|
|
25887
26145
|
${preview.sampleIncluded?.length ? html4`
|
|
25888
26146
|
<details>
|
|
@@ -25915,10 +26173,7 @@ function ChipFormRow({
|
|
|
25915
26173
|
};
|
|
25916
26174
|
return html4`
|
|
25917
26175
|
<div class="form-row">
|
|
25918
|
-
<span class="lbl">
|
|
25919
|
-
${label}
|
|
25920
|
-
${sub ? html4`<span style="color:var(--fg-3);font-weight:400;text-transform:none;letter-spacing:0"> · ${sub}</span>` : null}
|
|
25921
|
-
</span>
|
|
26176
|
+
<span class="lbl">${label}${sub ? html4`<span style="color:var(--fg-3);font-weight:400;text-transform:none;letter-spacing:0"> · ${sub}</span>` : null}</span>
|
|
25922
26177
|
<div style="display:flex;flex-wrap:wrap;gap:4px">
|
|
25923
26178
|
${value.map(
|
|
25924
26179
|
(e3) => html4`
|
|
@@ -25949,22 +26204,27 @@ function ChipFormRow({
|
|
|
25949
26204
|
function SemanticJobView({ job, running }) {
|
|
25950
26205
|
useLang();
|
|
25951
26206
|
const phaseLabel = {
|
|
26207
|
+
setup: t4("semantic.phaseSetup"),
|
|
25952
26208
|
scan: t4("semantic.phaseScan"),
|
|
25953
26209
|
embed: t4("semantic.phaseEmbed"),
|
|
25954
26210
|
write: t4("semantic.phaseWrite"),
|
|
25955
26211
|
done: t4("semantic.phaseDone"),
|
|
25956
|
-
error: t4("semantic.phaseError")
|
|
26212
|
+
error: t4("semantic.phaseError"),
|
|
26213
|
+
cancelled: t4("semantic.phaseCancelled")
|
|
25957
26214
|
}[job.phase] ?? job.phase;
|
|
25958
26215
|
const total = job.chunksTotal ?? 0;
|
|
25959
26216
|
const doneN = job.chunksDone ?? 0;
|
|
25960
26217
|
const ratio = total > 0 ? Math.min(1, doneN / total) : 0;
|
|
25961
|
-
const
|
|
26218
|
+
const elapsedBase = job.finishedAt ?? Date.now();
|
|
26219
|
+
const elapsedSeconds = (elapsedBase - job.startedAt) / 1e3;
|
|
26220
|
+
const elapsed = elapsedSeconds < 0.1 ? "<0.1s" : `${elapsedSeconds.toFixed(1)}s`;
|
|
26221
|
+
const phaseSummary = job.phase === "error" && job.lastPhase === "setup" ? t4("semantic.setupFailed") : phaseLabel;
|
|
25962
26222
|
return html4`
|
|
25963
26223
|
<div class="kv">
|
|
25964
26224
|
<div><span class="kv-key">phase</span>
|
|
25965
|
-
<span class=${`pill ${job.phase === "error" ? "pill-err" : running ? "pill-active" : "pill-dim"}`}>${
|
|
25966
|
-
${job.aborted ? html4`<span class="pill warn" style="margin-left: 6px;">${t4("semantic.stopping")}</span>` : null}
|
|
25967
|
-
<span style="color:var(--fg-3);margin-left:8px">${elapsed}
|
|
26225
|
+
<span class=${`pill ${job.phase === "error" ? "pill-err" : job.phase === "cancelled" ? "warn" : running ? "pill-active" : "pill-dim"}`}>${phaseSummary}</span>
|
|
26226
|
+
${job.aborted && running ? html4`<span class="pill warn" style="margin-left: 6px;">${t4("semantic.stopping")}</span>` : null}
|
|
26227
|
+
<span style="color:var(--fg-3);margin-left:8px">${elapsed}</span>
|
|
25968
26228
|
</div>
|
|
25969
26229
|
${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}
|
|
25970
26230
|
${total > 0 ? html4`
|
|
@@ -25998,6 +26258,14 @@ function SkipBucketsView({ buckets }) {
|
|
|
25998
26258
|
const parts = order.filter(([k3]) => (buckets[k3] || 0) > 0).map(([k3, label]) => `${label}: ${buckets[k3]}`);
|
|
25999
26259
|
return html4`<div><span class="kv-key">${t4("semantic.skipped")}</span>${t4("semantic.skippedFiles", { total, details: parts.join(", ") })}</div>`;
|
|
26000
26260
|
}
|
|
26261
|
+
function isActiveSemanticPhase(phase) {
|
|
26262
|
+
return phase === "setup" || phase === "scan" || phase === "embed" || phase === "write";
|
|
26263
|
+
}
|
|
26264
|
+
function isPlainObject(value) {
|
|
26265
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
26266
|
+
const proto = Object.getPrototypeOf(value);
|
|
26267
|
+
return proto === Object.prototype || proto === null;
|
|
26268
|
+
}
|
|
26001
26269
|
|
|
26002
26270
|
// dashboard/src/panels/sessions.ts
|
|
26003
26271
|
function SessionsPanel() {
|