@icen.ai/ui 0.8.0 → 0.9.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/AGENTS.md +63 -14
- package/README.md +17 -9
- package/dist/base.css +4 -3
- package/dist/behaviors/accordion.d.mts +5 -2
- package/dist/behaviors/accordion.mjs +36 -11
- package/dist/behaviors/ai-branch.d.mts +19 -0
- package/dist/behaviors/ai-branch.mjs +217 -0
- package/dist/behaviors/ai-chat.d.mts +11 -7
- package/dist/behaviors/ai-chat.mjs +134 -51
- package/dist/behaviors/ai-composer.d.mts +28 -3
- package/dist/behaviors/ai-composer.mjs +399 -229
- package/dist/behaviors/ai-core.d.mts +9 -4
- package/dist/behaviors/ai-core.mjs +21 -8
- package/dist/behaviors/ai-diff.d.mts +2 -2
- package/dist/behaviors/ai-diff.mjs +172 -41
- package/dist/behaviors/ai-feedback.d.mts +26 -0
- package/dist/behaviors/ai-feedback.mjs +303 -0
- package/dist/behaviors/ai-panel.d.mts +26 -9
- package/dist/behaviors/ai-panel.mjs +211 -110
- package/dist/behaviors/ai-provider.mjs +54 -48
- package/dist/behaviors/ai-threads.d.mts +38 -0
- package/dist/behaviors/ai-threads.mjs +319 -0
- package/dist/behaviors/ai-tool.d.mts +12 -4
- package/dist/behaviors/ai-tool.mjs +316 -263
- package/dist/behaviors/ai-tools.d.mts +9 -6
- package/dist/behaviors/ai-tools.mjs +264 -155
- package/dist/behaviors/back-top.mjs +16 -1
- package/dist/behaviors/carousel.d.mts +5 -2
- package/dist/behaviors/carousel.mjs +53 -26
- package/dist/behaviors/charts.d.mts +170 -22
- package/dist/behaviors/charts.mjs +1016 -150
- package/dist/behaviors/command-palette.d.mts +40 -6
- package/dist/behaviors/command-palette.mjs +143 -15
- package/dist/behaviors/context-menu.d.mts +21 -4
- package/dist/behaviors/context-menu.mjs +122 -38
- package/dist/behaviors/controls.d.mts +59 -0
- package/dist/behaviors/controls.mjs +601 -0
- package/dist/behaviors/copy.d.mts +5 -2
- package/dist/behaviors/copy.mjs +37 -12
- package/dist/behaviors/datatable.d.mts +12 -0
- package/dist/behaviors/datatable.mjs +226 -43
- package/dist/behaviors/date-picker.d.mts +2 -2
- package/dist/behaviors/date-picker.mjs +171 -32
- package/dist/behaviors/dropdown.d.mts +6 -2
- package/dist/behaviors/dropdown.mjs +164 -25
- package/dist/behaviors/events.d.mts +523 -0
- package/dist/behaviors/events.mjs +208 -0
- package/dist/behaviors/input.mjs +25 -12
- package/dist/behaviors/kb-access.d.mts +34 -0
- package/dist/behaviors/kb-access.mjs +569 -0
- package/dist/behaviors/kb-acl.d.mts +50 -0
- package/dist/behaviors/kb-acl.mjs +405 -0
- package/dist/behaviors/kb-answer.d.mts +38 -0
- package/dist/behaviors/kb-answer.mjs +2055 -0
- package/dist/behaviors/kb-audit.d.mts +23 -0
- package/dist/behaviors/kb-audit.mjs +375 -0
- package/dist/behaviors/kb-canvas.d.mts +44 -0
- package/dist/behaviors/kb-canvas.mjs +589 -0
- package/dist/behaviors/kb-chain.d.mts +15 -0
- package/dist/behaviors/kb-chain.mjs +270 -0
- package/dist/behaviors/kb-checkpoint.d.mts +16 -0
- package/dist/behaviors/kb-checkpoint.mjs +342 -0
- package/dist/behaviors/kb-chunks.d.mts +31 -0
- package/dist/behaviors/kb-chunks.mjs +475 -0
- package/dist/behaviors/kb-citation.d.mts +38 -0
- package/dist/behaviors/kb-citation.mjs +677 -0
- package/dist/behaviors/kb-clarify.d.mts +20 -0
- package/dist/behaviors/kb-clarify.mjs +248 -0
- package/dist/behaviors/kb-conflict.d.mts +22 -0
- package/dist/behaviors/kb-conflict.mjs +284 -0
- package/dist/behaviors/kb-connector.d.mts +17 -0
- package/dist/behaviors/kb-connector.mjs +375 -0
- package/dist/behaviors/kb-core.d.mts +529 -0
- package/dist/behaviors/kb-core.mjs +890 -0
- package/dist/behaviors/kb-eval.d.mts +22 -0
- package/dist/behaviors/kb-eval.mjs +408 -0
- package/dist/behaviors/kb-explain.d.mts +11 -0
- package/dist/behaviors/kb-explain.mjs +243 -0
- package/dist/behaviors/kb-filter.d.mts +31 -0
- package/dist/behaviors/kb-filter.mjs +587 -0
- package/dist/behaviors/kb-gap.d.mts +27 -0
- package/dist/behaviors/kb-gap.mjs +273 -0
- package/dist/behaviors/kb-hittest.d.mts +34 -0
- package/dist/behaviors/kb-hittest.mjs +409 -0
- package/dist/behaviors/kb-metadata.d.mts +29 -0
- package/dist/behaviors/kb-metadata.mjs +326 -0
- package/dist/behaviors/kb-passage.d.mts +41 -0
- package/dist/behaviors/kb-passage.mjs +529 -0
- package/dist/behaviors/kb-pipeline.d.mts +18 -0
- package/dist/behaviors/kb-pipeline.mjs +381 -0
- package/dist/behaviors/kb-qa.d.mts +26 -0
- package/dist/behaviors/kb-qa.mjs +332 -0
- package/dist/behaviors/kb-rerank.d.mts +20 -0
- package/dist/behaviors/kb-rerank.mjs +315 -0
- package/dist/behaviors/kb-retrieval.d.mts +49 -0
- package/dist/behaviors/kb-retrieval.mjs +746 -0
- package/dist/behaviors/kb-review.d.mts +44 -0
- package/dist/behaviors/kb-review.mjs +451 -0
- package/dist/behaviors/kb-sandbox.d.mts +33 -0
- package/dist/behaviors/kb-sandbox.mjs +325 -0
- package/dist/behaviors/kb-segment.d.mts +32 -0
- package/dist/behaviors/kb-segment.mjs +499 -0
- package/dist/behaviors/kb-sources.d.mts +27 -0
- package/dist/behaviors/kb-sources.mjs +373 -0
- package/dist/behaviors/kb-sql.d.mts +43 -0
- package/dist/behaviors/kb-sql.mjs +948 -0
- package/dist/behaviors/kb-trace.d.mts +16 -0
- package/dist/behaviors/kb-trace.mjs +414 -0
- package/dist/behaviors/kb-visibility.d.mts +44 -0
- package/dist/behaviors/kb-visibility.mjs +403 -0
- package/dist/behaviors/kb-who-can.d.mts +32 -0
- package/dist/behaviors/kb-who-can.mjs +379 -0
- package/dist/behaviors/modal.d.mts +24 -5
- package/dist/behaviors/modal.mjs +76 -10
- package/dist/behaviors/nav.d.mts +1 -1
- package/dist/behaviors/nav.mjs +33 -7
- package/dist/behaviors/notification.d.mts +20 -4
- package/dist/behaviors/notification.mjs +53 -73
- package/dist/behaviors/popover.d.mts +39 -3
- package/dist/behaviors/popover.mjs +90 -4
- package/dist/behaviors/select.d.mts +4 -2
- package/dist/behaviors/select.mjs +161 -24
- package/dist/behaviors/sidebar.d.mts +5 -2
- package/dist/behaviors/sidebar.mjs +43 -13
- package/dist/behaviors/slider.d.mts +5 -2
- package/dist/behaviors/slider.mjs +54 -43
- package/dist/behaviors/split-pane.d.mts +6 -2
- package/dist/behaviors/split-pane.mjs +62 -21
- package/dist/behaviors/tabs.d.mts +3 -2
- package/dist/behaviors/tabs.mjs +65 -14
- package/dist/behaviors/tag-input.d.mts +5 -2
- package/dist/behaviors/tag-input.mjs +61 -21
- package/dist/behaviors/theme.d.mts +13 -2
- package/dist/behaviors/theme.mjs +48 -4
- package/dist/behaviors/toast.d.mts +30 -8
- package/dist/behaviors/toast.mjs +74 -7
- package/dist/behaviors/tree.d.mts +5 -2
- package/dist/behaviors/tree.mjs +38 -15
- package/dist/behaviors/upload.mjs +21 -23
- package/dist/cli.mjs +1 -1
- package/dist/components/ai-branch.mjs +3 -0
- package/dist/components/ai-chat.css +295 -0
- package/dist/components/ai-feedback.mjs +3 -0
- package/dist/components/ai-panel.css +218 -1
- package/dist/components/ai-threads.mjs +3 -0
- package/dist/components/ai-tool-call.mjs +1 -1
- package/dist/components/badge.css +1 -1
- package/dist/components/breadcrumb.css +0 -32
- package/dist/components/chart-calendar.mjs +1 -2
- package/dist/components/chart-graph.css +57 -0
- package/dist/components/chart-graph.mjs +4 -0
- package/dist/components/chart-map.mjs +3 -0
- package/dist/components/chart-pie.css +0 -6
- package/dist/components/chart-scatter.mjs +1 -1
- package/dist/components/charts.css +33 -1
- package/dist/components/charts.mjs +1 -0
- package/dist/components/content.css +3 -16
- package/dist/components/datatable.css +1 -1
- package/dist/components/date-picker.css +1 -1
- package/dist/components/kb-access.mjs +4 -0
- package/dist/components/kb-acl.mjs +4 -0
- package/dist/components/kb-agent.css +481 -0
- package/dist/components/kb-answer.mjs +4 -0
- package/dist/components/kb-audit.mjs +4 -0
- package/dist/components/kb-canvas.mjs +4 -0
- package/dist/components/kb-chain.mjs +4 -0
- package/dist/components/kb-checkpoint.mjs +4 -0
- package/dist/components/kb-chunks.mjs +4 -0
- package/dist/components/kb-citation.mjs +4 -0
- package/dist/components/kb-clarify.mjs +4 -0
- package/dist/components/kb-conflict.mjs +4 -0
- package/dist/components/kb-connector.mjs +4 -0
- package/dist/components/kb-data.css +649 -0
- package/dist/components/kb-eval.mjs +4 -0
- package/dist/components/kb-explain.mjs +4 -0
- package/dist/components/kb-filter.mjs +4 -0
- package/dist/components/kb-gap.mjs +4 -0
- package/dist/components/kb-ground.css +566 -0
- package/dist/components/kb-hittest.mjs +4 -0
- package/dist/components/kb-ingest.css +898 -0
- package/dist/components/kb-metadata.mjs +4 -0
- package/dist/components/kb-ops.css +548 -0
- package/dist/components/kb-passage.mjs +4 -0
- package/dist/components/kb-perm.css +444 -0
- package/dist/components/kb-pipeline.mjs +4 -0
- package/dist/components/kb-qa.mjs +4 -0
- package/dist/components/kb-rerank.mjs +4 -0
- package/dist/components/kb-retrieval.mjs +4 -0
- package/dist/components/kb-review.mjs +4 -0
- package/dist/components/kb-sandbox.mjs +4 -0
- package/dist/components/kb-search.css +940 -0
- package/dist/components/kb-segment.mjs +4 -0
- package/dist/components/kb-sources.mjs +4 -0
- package/dist/components/kb-sql.mjs +4 -0
- package/dist/components/kb-trace.mjs +4 -0
- package/dist/components/kb-visibility.mjs +4 -0
- package/dist/components/kb-who-can.mjs +4 -0
- package/dist/components/kb.css +252 -0
- package/dist/components/kb.mjs +9 -0
- package/dist/components/notification.css +2 -3
- package/dist/components/pagination.css +3 -1
- package/dist/components/pagination.mjs +1 -0
- package/dist/components/rating.mjs +1 -0
- package/dist/components/segmented.css +9 -1
- package/dist/components/segmented.mjs +1 -1
- package/dist/components/select.css +67 -4
- package/dist/components/steps.css +13 -3
- package/dist/components/steps.mjs +1 -0
- package/dist/components/switch.css +3 -1
- package/dist/components/switch.mjs +1 -0
- package/dist/components/table.mjs +1 -0
- package/dist/components/tabs.css +23 -0
- package/dist/components/tag-input.css +1 -6
- package/dist/components/upload.css +0 -15
- package/dist/index.d.mts +48 -11
- package/dist/index.mjs +13205 -3615
- package/dist/registry.json +366 -15
- package/dist/retro-effects.css +3 -16
- package/dist/tokens/retro-effects.css +3 -16
- package/dist/tokens/style-profiles.css +3 -2
- package/dist/tokens/typography.css +2 -0
- package/dist/tokens.css +5 -2
- package/dist/ui.css +5713 -267
- package/docs/research/2026-10-03-ai-kb-components.md +392 -0
- package/docs/research/2026-10-03-kb-permissions.md +992 -0
- package/docs/spec/ai-native.md +7 -4
- package/docs/spec/kb-family.md +443 -0
- package/package.json +2 -2
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { KbSpan } from './kb-core.js';
|
|
2
|
+
import './ai-core.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 渲染 trace span 树(快照:整体替换 el 内容)。返回挂载容器 el。
|
|
6
|
+
* spans 建议先经 kb-core normalizeSpans;本函数内部会再归一一次以保证父先子后与 kind/status 合法。
|
|
7
|
+
*/
|
|
8
|
+
declare function renderKbTrace(el: HTMLElement, spans: KbSpan[]): HTMLElement;
|
|
9
|
+
/**
|
|
10
|
+
* 初始化 trace 树交互:document 级委托(click 选中+折叠;Enter/Space 展开聚焦行)。
|
|
11
|
+
* 幂等(重复调用安全);返回销毁函数(解绑委托并复位幂等标记,销毁后可重新 init)。
|
|
12
|
+
* 委托挂 document 级:动态插入的 .kb-trace 自动接管,无需重跑 init(root 参数仅保持 kb 族 API 对称)。
|
|
13
|
+
*/
|
|
14
|
+
declare function initKbTrace(root?: ParentNode): () => void;
|
|
15
|
+
|
|
16
|
+
export { initKbTrace, renderKbTrace };
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
// src/behaviors/ai-core.ts
|
|
2
|
+
var svg = (body) => `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${body}</svg>`;
|
|
3
|
+
var ICON_TERMINAL = svg('<path d="m4 17 6-6-6-6"/><path d="M12 19h8"/>');
|
|
4
|
+
var ICON_FILE = svg(
|
|
5
|
+
'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/>'
|
|
6
|
+
);
|
|
7
|
+
var ICON_FILE_PEN = svg(
|
|
8
|
+
'<path d="M12.5 22H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8l5 5v3.5"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M19 6.5 16.5 4"/><path d="M21.378 16.626a1 1 0 0 0-3.004-3.004l-4.01 4.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z"/>'
|
|
9
|
+
);
|
|
10
|
+
var ICON_FILE_PLUS = svg(
|
|
11
|
+
'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M9 15h6"/><path d="M12 12v6"/>'
|
|
12
|
+
);
|
|
13
|
+
var ICON_TRASH = svg(
|
|
14
|
+
'<path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M10 11v6"/><path d="M14 11v6"/>'
|
|
15
|
+
);
|
|
16
|
+
var ICON_SEARCH = svg('<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>');
|
|
17
|
+
var ICON_FOLDER_SEARCH = svg(
|
|
18
|
+
'<path d="M11 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v4"/><circle cx="17" cy="17" r="3"/><path d="m21 21-1.9-1.9"/>'
|
|
19
|
+
);
|
|
20
|
+
var ICON_SCAN_SEARCH = svg(
|
|
21
|
+
'<path d="M3 7V5a2 2 0 0 1 2-2h2"/><path d="M17 3h2a2 2 0 0 1 2 2v2"/><path d="M21 17v2a2 2 0 0 1-2 2h-2"/><path d="M7 21H5a2 2 0 0 1-2-2v-2"/><circle cx="12" cy="12" r="3"/><path d="m16 16-1.9-1.9"/>'
|
|
22
|
+
);
|
|
23
|
+
var ICON_GLOBE = svg(
|
|
24
|
+
'<circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/>'
|
|
25
|
+
);
|
|
26
|
+
var ICON_DOWNLOAD = svg(
|
|
27
|
+
'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/><path d="M12 15V3"/>'
|
|
28
|
+
);
|
|
29
|
+
var ICON_BLOCKS = svg(
|
|
30
|
+
'<rect width="7" height="7" x="4" y="4" rx="1"/><rect width="7" height="7" x="13" y="4" rx="1"/><rect width="7" height="7" x="4" y="13" rx="1"/><rect width="7" height="7" x="13" y="13" rx="1"/>'
|
|
31
|
+
);
|
|
32
|
+
var ICON_ZAP = svg(
|
|
33
|
+
'<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/>'
|
|
34
|
+
);
|
|
35
|
+
var ICON_LIST = svg(
|
|
36
|
+
'<path d="M3 12h.01"/><path d="M3 18h.01"/><path d="M3 6h.01"/><path d="M8 12h13"/><path d="M8 18h13"/><path d="M8 6h13"/>'
|
|
37
|
+
);
|
|
38
|
+
var ICON_LIST_CHECKS = svg(
|
|
39
|
+
'<path d="m3 17 2 2 4-4"/><path d="m3 7 2 2 4-4"/><path d="M13 6h8"/><path d="M13 12h8"/><path d="M13 18h8"/>'
|
|
40
|
+
);
|
|
41
|
+
var ICON_BOT = svg(
|
|
42
|
+
'<path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/>'
|
|
43
|
+
);
|
|
44
|
+
var ICON_CHART = svg(
|
|
45
|
+
'<path d="M3 3v18h18"/><path d="M7 15l4-6 3 4 5-8"/>'
|
|
46
|
+
);
|
|
47
|
+
var ICON_FILE_TEXT = svg(
|
|
48
|
+
'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8"/><path d="M16 13H8"/><path d="M16 17H8"/>'
|
|
49
|
+
);
|
|
50
|
+
function isObj(v) {
|
|
51
|
+
return typeof v === "object" && v !== null;
|
|
52
|
+
}
|
|
53
|
+
function pickStr(input, keys) {
|
|
54
|
+
if (!isObj(input)) return void 0;
|
|
55
|
+
for (const k of keys) {
|
|
56
|
+
const v = input[k];
|
|
57
|
+
if (typeof v === "string" && v) return v;
|
|
58
|
+
}
|
|
59
|
+
return void 0;
|
|
60
|
+
}
|
|
61
|
+
function pickNum(src, keys) {
|
|
62
|
+
if (!isObj(src)) return void 0;
|
|
63
|
+
for (const k of keys) {
|
|
64
|
+
const v = src[k];
|
|
65
|
+
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
66
|
+
}
|
|
67
|
+
return void 0;
|
|
68
|
+
}
|
|
69
|
+
function firstLine(s, max = 80) {
|
|
70
|
+
const line = s.split("\n", 1)[0]?.trim() ?? "";
|
|
71
|
+
return line.length > max ? `${line.slice(0, max)}\u2026` : line;
|
|
72
|
+
}
|
|
73
|
+
function filePathOf(input) {
|
|
74
|
+
return pickStr(input, ["file_path", "path", "file", "filename"]);
|
|
75
|
+
}
|
|
76
|
+
var summarizePath = (input) => filePathOf(input);
|
|
77
|
+
function summarizeRead(input) {
|
|
78
|
+
const p = filePathOf(input);
|
|
79
|
+
if (!p) return void 0;
|
|
80
|
+
const offset = pickNum(input, ["offset", "start_line"]);
|
|
81
|
+
if (offset == null) return p;
|
|
82
|
+
const limit = pickNum(input, ["limit", "end_line"]);
|
|
83
|
+
return limit != null ? `${p}:${offset}-${offset + limit}` : `${p}:${offset}`;
|
|
84
|
+
}
|
|
85
|
+
function summarizeShell(input) {
|
|
86
|
+
const cmd = typeof input === "string" ? input : pickStr(input, ["command", "cmd", "script"]);
|
|
87
|
+
return cmd ? firstLine(cmd) : void 0;
|
|
88
|
+
}
|
|
89
|
+
function summarizeGrep(input) {
|
|
90
|
+
const pattern = pickStr(input, ["pattern", "regex", "query"]);
|
|
91
|
+
const p = filePathOf(input);
|
|
92
|
+
if (pattern) return p ? `${firstLine(pattern, 40)} \xB7 ${p}` : firstLine(pattern);
|
|
93
|
+
return p;
|
|
94
|
+
}
|
|
95
|
+
var sum = (fn) => {
|
|
96
|
+
return (input) => fn(input) ?? "";
|
|
97
|
+
};
|
|
98
|
+
var BUILTIN_KINDS = {
|
|
99
|
+
shell: { label: "\u547D\u4EE4", icon: ICON_TERMINAL, tint: "accent", summarize: sum(summarizeShell) },
|
|
100
|
+
read: { label: "\u8BFB\u53D6", icon: ICON_FILE, tint: "info", summarize: sum(summarizeRead) },
|
|
101
|
+
edit: { label: "\u7F16\u8F91", icon: ICON_FILE_PEN, tint: "warning", summarize: sum(summarizePath) },
|
|
102
|
+
write: { label: "\u5199\u5165", icon: ICON_FILE_PLUS, tint: "warning", summarize: sum(summarizePath) },
|
|
103
|
+
rm: { label: "\u5220\u9664", icon: ICON_TRASH, tint: "error", summarize: sum(summarizePath) },
|
|
104
|
+
grep: { label: "\u641C\u7D22", icon: ICON_SEARCH, tint: "info", summarize: sum(summarizeGrep) },
|
|
105
|
+
glob: { label: "\u5339\u914D", icon: ICON_FOLDER_SEARCH, tint: "info", summarize: sum((i) => pickStr(i, ["pattern", "glob", "path"])) },
|
|
106
|
+
browser: { label: "\u6D4F\u89C8", icon: ICON_GLOBE, tint: "accent", summarize: sum((i) => pickStr(i, ["url", "uri", "target"])) },
|
|
107
|
+
search: { label: "\u68C0\u7D22", icon: ICON_SCAN_SEARCH, tint: "accent", summarize: sum((i) => pickStr(i, ["query", "q", "pattern"])) },
|
|
108
|
+
fetch: { label: "\u8BF7\u6C42", icon: ICON_DOWNLOAD, tint: "info", summarize: sum((i) => pickStr(i, ["url", "uri", "endpoint"])) },
|
|
109
|
+
mcp: { label: "MCP", icon: ICON_BLOCKS, tint: "muted", summarize: sum((i) => pickStr(i, ["tool", "method", "name"])) },
|
|
110
|
+
skill: { label: "\u6280\u80FD", icon: ICON_ZAP, tint: "accent", summarize: sum((i) => pickStr(i, ["skill", "name", "command"])) },
|
|
111
|
+
todo: {
|
|
112
|
+
label: "\u5F85\u529E",
|
|
113
|
+
icon: ICON_LIST,
|
|
114
|
+
tint: "info",
|
|
115
|
+
summarize: sum((input) => {
|
|
116
|
+
const items = input && typeof input === "object" && Array.isArray(input.items) ? input.items : Array.isArray(input) ? input : [];
|
|
117
|
+
const done = items.filter((it) => it?.status === "done").length;
|
|
118
|
+
return items.length > 0 ? `${done}/${items.length} \u5B8C\u6210` : "";
|
|
119
|
+
})
|
|
120
|
+
},
|
|
121
|
+
plan: { label: "\u8BA1\u5212", icon: ICON_LIST_CHECKS, tint: "info" },
|
|
122
|
+
subagent: { label: "\u5B50\u4EE3\u7406", icon: ICON_BOT, tint: "accent", summarize: sum((i) => pickStr(i, ["task", "description", "prompt", "message", "subagent_type"])) },
|
|
123
|
+
note: { label: "\u7B14\u8BB0", icon: ICON_FILE_TEXT, tint: "muted" },
|
|
124
|
+
chart: { label: "\u56FE\u8868", icon: ICON_CHART, tint: "info", summarize: sum((i) => pickStr(i, ["title", "name"])) }
|
|
125
|
+
};
|
|
126
|
+
var kindRegistry = new Map(Object.entries(BUILTIN_KINDS));
|
|
127
|
+
function h(tag, className, text) {
|
|
128
|
+
const node = document.createElement(tag);
|
|
129
|
+
if (className) node.className = className;
|
|
130
|
+
if (text != null) node.textContent = text;
|
|
131
|
+
return node;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// src/behaviors/kb-core.ts
|
|
135
|
+
var ic = (label, d) => ({ label, icon: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">${d}</svg>` });
|
|
136
|
+
var BUILTIN_SOURCE_TYPES = {
|
|
137
|
+
doc: ic("\u6587\u6863", '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/>'),
|
|
138
|
+
web: ic("\u7F51\u9875", '<circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15 15 0 0 1 0 20 15 15 0 0 1 0-20z"/>'),
|
|
139
|
+
wiki: ic("\u77E5\u8BC6\u5E93", '<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/>'),
|
|
140
|
+
sheet: ic("\u8868\u683C", '<rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M3 15h18M9 3v18M15 3v18"/>'),
|
|
141
|
+
db: ic("\u6570\u636E\u5E93", '<ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14c0 1.7 4 3 9 3s9-1.3 9-3V5"/><path d="M3 12c0 1.7 4 3 9 3s9-1.3 9-3"/>'),
|
|
142
|
+
ticket: ic("\u5DE5\u5355", '<path d="M3 9V7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v2a2 2 0 0 0 0 6v2a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2a2 2 0 0 0 0-6z"/><path d="M13 5v14"/>'),
|
|
143
|
+
code: ic("\u4EE3\u7801", '<path d="m16 18 6-6-6-6"/><path d="m8 6-6 6 6 6"/>'),
|
|
144
|
+
api: ic("\u63A5\u53E3", '<path d="M4 7a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3a2 2 0 0 0 0 4v3a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-3a2 2 0 0 0 0-4z"/>'),
|
|
145
|
+
image: ic("\u56FE\u7247", '<rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-4.6-4.6a2 2 0 0 0-2.8 0L3 21"/>'),
|
|
146
|
+
mail: ic("\u90AE\u4EF6", '<rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-10 7L2 7"/>')
|
|
147
|
+
};
|
|
148
|
+
var sourceTypeRegistry = new Map(Object.entries(BUILTIN_SOURCE_TYPES));
|
|
149
|
+
var LOWER_IS_BETTER = /* @__PURE__ */ new Set(["l2"]);
|
|
150
|
+
function scoreHigherIsBetter(kind) {
|
|
151
|
+
return kind != null && LOWER_IS_BETTER.has(kind) ? false : true;
|
|
152
|
+
}
|
|
153
|
+
function formatScore(v, digits = 3) {
|
|
154
|
+
if (v == null || !Number.isFinite(v)) return "\u2014";
|
|
155
|
+
return v.toFixed(digits).replace(/\.?0+$/, (s) => s.includes(".") ? "" : s);
|
|
156
|
+
}
|
|
157
|
+
function scorePercent(v, kind, max = 1) {
|
|
158
|
+
if (v == null || !Number.isFinite(v)) return null;
|
|
159
|
+
const pct = scoreHigherIsBetter(kind) ? v / max * 100 : (1 - v / max) * 100;
|
|
160
|
+
return Math.max(0, Math.min(100, pct));
|
|
161
|
+
}
|
|
162
|
+
function normalizeHit(raw) {
|
|
163
|
+
const score = typeof raw.score === "number" && Number.isFinite(raw.score) ? raw.score : null;
|
|
164
|
+
return {
|
|
165
|
+
chunkId: String(raw.chunkId ?? raw.id ?? ""),
|
|
166
|
+
documentId: typeof raw.documentId === "string" ? raw.documentId : void 0,
|
|
167
|
+
title: typeof raw.title === "string" ? raw.title : void 0,
|
|
168
|
+
snippet: String(raw.snippet ?? raw.content ?? ""),
|
|
169
|
+
score,
|
|
170
|
+
scoreKind: raw.scoreKind,
|
|
171
|
+
vectorPart: typeof raw.vectorPart === "number" ? raw.vectorPart : void 0,
|
|
172
|
+
keywordPart: typeof raw.keywordPart === "number" ? raw.keywordPart : void 0,
|
|
173
|
+
explain: typeof raw.explain === "string" ? raw.explain : void 0,
|
|
174
|
+
page: typeof raw.page === "number" ? raw.page : void 0,
|
|
175
|
+
meta: raw.meta && typeof raw.meta === "object" ? raw.meta : void 0
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
var KB_SPAN_KINDS = [
|
|
179
|
+
"retrieval",
|
|
180
|
+
"generation",
|
|
181
|
+
"rerank",
|
|
182
|
+
"embed",
|
|
183
|
+
"tool",
|
|
184
|
+
"guard",
|
|
185
|
+
"chunk",
|
|
186
|
+
"query",
|
|
187
|
+
"agent"
|
|
188
|
+
];
|
|
189
|
+
var SPAN_LABELS = {
|
|
190
|
+
retrieval: "\u68C0\u7D22",
|
|
191
|
+
generation: "\u751F\u6210",
|
|
192
|
+
rerank: "\u91CD\u6392",
|
|
193
|
+
embed: "\u5411\u91CF\u5316",
|
|
194
|
+
tool: "\u5DE5\u5177",
|
|
195
|
+
guard: "\u62A4\u680F",
|
|
196
|
+
chunk: "\u5207\u7247",
|
|
197
|
+
query: "\u67E5\u8BE2",
|
|
198
|
+
agent: "\u4EE3\u7406"
|
|
199
|
+
};
|
|
200
|
+
function kbSpanKindLabel(k) {
|
|
201
|
+
return SPAN_LABELS[k] ?? k;
|
|
202
|
+
}
|
|
203
|
+
function toSpanStatus(v) {
|
|
204
|
+
return v === "running" || v === "error" || v === "cancel" ? v : "done";
|
|
205
|
+
}
|
|
206
|
+
function normalizeSpans(raw) {
|
|
207
|
+
const spans = raw.map((r) => ({
|
|
208
|
+
id: String(r.id ?? ""),
|
|
209
|
+
parentId: typeof r.parentId === "string" ? r.parentId : void 0,
|
|
210
|
+
kind: KB_SPAN_KINDS.includes(r.kind) ? r.kind : "tool",
|
|
211
|
+
name: String(r.name ?? ""),
|
|
212
|
+
status: toSpanStatus(r.status),
|
|
213
|
+
startedAt: typeof r.startedAt === "number" || typeof r.startedAt === "string" ? r.startedAt : void 0,
|
|
214
|
+
elapsedMs: typeof r.elapsedMs === "number" ? r.elapsedMs : void 0,
|
|
215
|
+
detail: typeof r.detail === "string" ? r.detail : void 0,
|
|
216
|
+
usage: r.usage && typeof r.usage === "object" ? r.usage : void 0,
|
|
217
|
+
hits: Array.isArray(r.hits) ? r.hits.map((h2) => normalizeHit(h2)) : void 0,
|
|
218
|
+
error: typeof r.error === "string" ? r.error : void 0
|
|
219
|
+
})).filter((s) => s.id);
|
|
220
|
+
const byId = new Map(spans.map((s) => [s.id, s]));
|
|
221
|
+
return [...spans].sort((a, b) => {
|
|
222
|
+
const da = depthOf(a, byId, 0);
|
|
223
|
+
const db = depthOf(b, byId, 0);
|
|
224
|
+
return da === db ? indexIn(spans, a) - indexIn(spans, b) : da - db;
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
function depthOf(span, byId, guard) {
|
|
228
|
+
if (guard > 32 || !span.parentId) return 0;
|
|
229
|
+
const parent = byId.get(span.parentId);
|
|
230
|
+
return parent ? depthOf(parent, byId, guard + 1) + 1 : 0;
|
|
231
|
+
}
|
|
232
|
+
function indexIn(spans, target) {
|
|
233
|
+
const i = spans.findIndex((s) => s.id === target.id);
|
|
234
|
+
return i === -1 ? spans.length : i;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// src/behaviors/events.ts
|
|
238
|
+
function emitIcen(source, type, detail) {
|
|
239
|
+
return source.dispatchEvent(
|
|
240
|
+
new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable: true })
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// src/behaviors/kb-trace.ts
|
|
245
|
+
var ROOT_KEY = "\0root";
|
|
246
|
+
function fmtElapsed(ms) {
|
|
247
|
+
if (ms == null || !Number.isFinite(ms)) return "\u2014";
|
|
248
|
+
return ms < 1e3 ? `${Math.round(ms)}ms` : `${(ms / 1e3).toFixed(1)}s`;
|
|
249
|
+
}
|
|
250
|
+
function depthOfSpan(span, byId, guard = 0) {
|
|
251
|
+
if (guard > 32 || !span.parentId) return 0;
|
|
252
|
+
const parent = byId.get(span.parentId);
|
|
253
|
+
return parent ? depthOfSpan(parent, byId, guard + 1) + 1 : 0;
|
|
254
|
+
}
|
|
255
|
+
function buildHitRow(hit, rank) {
|
|
256
|
+
const row = h("div", "kb-trace-hit");
|
|
257
|
+
row.append(h("span", "kb-trace-hit-rank kb-num", String(rank)));
|
|
258
|
+
row.append(h("span", "kb-trace-hit-title", hit.title || hit.snippet || hit.chunkId));
|
|
259
|
+
const score = h("span", "kb-score");
|
|
260
|
+
const bar = h("span", "kb-score-bar");
|
|
261
|
+
const fill = h("i");
|
|
262
|
+
const pct = scorePercent(hit.score, hit.scoreKind);
|
|
263
|
+
fill.style.width = pct != null ? `${pct}%` : "0%";
|
|
264
|
+
bar.append(fill);
|
|
265
|
+
score.append(bar, h("span", "kb-score-value", formatScore(hit.score)));
|
|
266
|
+
row.append(score);
|
|
267
|
+
return row;
|
|
268
|
+
}
|
|
269
|
+
function buildSpanBody(span) {
|
|
270
|
+
const usage = span.usage;
|
|
271
|
+
const hasUsage = !!(usage && (usage.inputTokens != null || usage.outputTokens != null || usage.costUsd != null));
|
|
272
|
+
const hasHits = span.kind === "retrieval" && !!span.hits && span.hits.length > 0;
|
|
273
|
+
if (!span.detail && !hasUsage && !hasHits && !span.error) return null;
|
|
274
|
+
const body = h("div", "kb-trace-body kb-fold-body");
|
|
275
|
+
if (span.detail) body.append(h("div", "kb-trace-detail", span.detail));
|
|
276
|
+
if (hasUsage && usage) {
|
|
277
|
+
const u = h("div", "kb-trace-usage");
|
|
278
|
+
if (usage.inputTokens != null) u.append(h("span", "kb-num", `\u2191 ${usage.inputTokens} tok`));
|
|
279
|
+
if (usage.outputTokens != null) u.append(h("span", "kb-num", `\u2193 ${usage.outputTokens} tok`));
|
|
280
|
+
if (usage.costUsd != null) u.append(h("span", "kb-num", `$${formatScore(usage.costUsd, 4)}`));
|
|
281
|
+
body.append(u);
|
|
282
|
+
}
|
|
283
|
+
if (hasHits && span.hits) {
|
|
284
|
+
const wrap = h("div", "kb-trace-hits");
|
|
285
|
+
wrap.append(h("div", "kb-trace-hits-label kb-meta", `\u547D\u4E2D ${span.hits.length}`));
|
|
286
|
+
span.hits.forEach((hit, i) => wrap.append(buildHitRow(hit, i + 1)));
|
|
287
|
+
body.append(wrap);
|
|
288
|
+
}
|
|
289
|
+
if (span.error) body.append(h("div", "kb-trace-error", span.error));
|
|
290
|
+
return body;
|
|
291
|
+
}
|
|
292
|
+
function applyTraceVisibility(trace) {
|
|
293
|
+
const rows = Array.from(trace.querySelectorAll(":scope > .kb-span"));
|
|
294
|
+
const byId = new Map(rows.map((r) => [r.dataset.spanId ?? "", r]));
|
|
295
|
+
for (const row of rows) {
|
|
296
|
+
const parent = row.dataset.parentId ? byId.get(row.dataset.parentId) : void 0;
|
|
297
|
+
row.hidden = parent ? parent.hidden || parent.getAttribute("aria-expanded") === "false" : false;
|
|
298
|
+
const next = row.nextElementSibling;
|
|
299
|
+
if (next instanceof HTMLElement && next.classList.contains("kb-trace-body")) {
|
|
300
|
+
next.hidden = row.hidden || row.getAttribute("aria-expanded") === "false";
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
function toggleSpanRow(trace, row) {
|
|
305
|
+
if (row.getAttribute("aria-expanded") == null) return;
|
|
306
|
+
const open = row.getAttribute("aria-expanded") !== "true";
|
|
307
|
+
row.setAttribute("aria-expanded", String(open));
|
|
308
|
+
row.classList.toggle("is-open", open);
|
|
309
|
+
applyTraceVisibility(trace);
|
|
310
|
+
emitIcen(trace, "icen:kb-trace-toggle", { spanId: row.dataset.spanId ?? "", open });
|
|
311
|
+
}
|
|
312
|
+
var bodyUid = 0;
|
|
313
|
+
function renderKbTrace(el, spans) {
|
|
314
|
+
if (typeof document === "undefined") return el;
|
|
315
|
+
const list = normalizeSpans(spans);
|
|
316
|
+
el.className = "kb-trace";
|
|
317
|
+
el.replaceChildren();
|
|
318
|
+
if (!list.length) {
|
|
319
|
+
el.append(h("div", "kb-empty", "\u6682\u65E0\u8C03\u7528\u94FE\u6570\u636E"));
|
|
320
|
+
return el;
|
|
321
|
+
}
|
|
322
|
+
const byId = new Map(list.map((s) => [s.id, s]));
|
|
323
|
+
const childIds = new Set(list.filter((s) => s.parentId && byId.has(s.parentId)).map((s) => s.parentId));
|
|
324
|
+
const maxByParent = /* @__PURE__ */ new Map();
|
|
325
|
+
for (const s of list) {
|
|
326
|
+
const key = s.parentId && byId.has(s.parentId) ? s.parentId : ROOT_KEY;
|
|
327
|
+
const v = typeof s.elapsedMs === "number" && s.elapsedMs > 0 ? s.elapsedMs : 0;
|
|
328
|
+
if (v > (maxByParent.get(key) ?? 0)) maxByParent.set(key, v);
|
|
329
|
+
}
|
|
330
|
+
for (const span of list) {
|
|
331
|
+
const depth = depthOfSpan(span, byId);
|
|
332
|
+
const key = span.parentId && byId.has(span.parentId) ? span.parentId : ROOT_KEY;
|
|
333
|
+
const max = maxByParent.get(key) ?? 0;
|
|
334
|
+
const ms = typeof span.elapsedMs === "number" && span.elapsedMs > 0 ? span.elapsedMs : 0;
|
|
335
|
+
const width = max > 0 && ms > 0 ? Math.max(2, ms / max * 100) : 0;
|
|
336
|
+
const hasKids = childIds.has(span.id);
|
|
337
|
+
const body = buildSpanBody(span);
|
|
338
|
+
const expandable = hasKids || body != null;
|
|
339
|
+
const open = expandable && (span.status === "error" || span.status === "running");
|
|
340
|
+
const row = h("div", `kb-span kb-span--${depth > 0 ? "child" : "root"} is-${span.kind} is-${span.status}`);
|
|
341
|
+
if (open) row.classList.add("is-open");
|
|
342
|
+
row.dataset.spanId = span.id;
|
|
343
|
+
if (span.parentId) row.dataset.parentId = span.parentId;
|
|
344
|
+
row.style.setProperty("--depth", String(depth));
|
|
345
|
+
row.tabIndex = 0;
|
|
346
|
+
row.setAttribute("role", "button");
|
|
347
|
+
if (expandable) row.setAttribute("aria-expanded", String(open));
|
|
348
|
+
const caret = h("span", "kb-span-caret");
|
|
349
|
+
caret.setAttribute("aria-hidden", "true");
|
|
350
|
+
caret.hidden = !hasKids;
|
|
351
|
+
row.append(
|
|
352
|
+
caret,
|
|
353
|
+
h("span", "kb-span-kind", kbSpanKindLabel(span.kind)),
|
|
354
|
+
h("span", "kb-span-name", span.name)
|
|
355
|
+
);
|
|
356
|
+
const bar = h("i", "kb-span-bar");
|
|
357
|
+
bar.style.width = `${width}%`;
|
|
358
|
+
row.append(bar, h("span", "kb-num", fmtElapsed(span.elapsedMs)));
|
|
359
|
+
el.append(row);
|
|
360
|
+
if (body) {
|
|
361
|
+
body.dataset.for = span.id;
|
|
362
|
+
body.style.setProperty("--depth", String(depth));
|
|
363
|
+
if (expandable) {
|
|
364
|
+
body.id = `kb-trace-body-${++bodyUid}`;
|
|
365
|
+
row.setAttribute("aria-controls", body.id);
|
|
366
|
+
}
|
|
367
|
+
body.hidden = !open;
|
|
368
|
+
el.append(body);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
applyTraceVisibility(el);
|
|
372
|
+
return el;
|
|
373
|
+
}
|
|
374
|
+
var traceInit = false;
|
|
375
|
+
var traceTeardown = null;
|
|
376
|
+
function initKbTrace(root) {
|
|
377
|
+
if (typeof document === "undefined" || traceInit) return () => {
|
|
378
|
+
};
|
|
379
|
+
traceInit = true;
|
|
380
|
+
const rowOf = (e) => {
|
|
381
|
+
const target = e.target;
|
|
382
|
+
if (!(target instanceof Element)) return null;
|
|
383
|
+
const row = target.closest(".kb-span");
|
|
384
|
+
if (!row) return null;
|
|
385
|
+
const trace = row.closest(".kb-trace");
|
|
386
|
+
return trace ? { row, trace } : null;
|
|
387
|
+
};
|
|
388
|
+
const onClick = (e) => {
|
|
389
|
+
const hit = rowOf(e);
|
|
390
|
+
if (!hit) return;
|
|
391
|
+
emitIcen(hit.trace, "icen:kb-trace-select", { spanId: hit.row.dataset.spanId ?? "" });
|
|
392
|
+
toggleSpanRow(hit.trace, hit.row);
|
|
393
|
+
};
|
|
394
|
+
const onKey = (e) => {
|
|
395
|
+
if (e.key !== "Enter" && e.key !== " ") return;
|
|
396
|
+
const hit = rowOf(e);
|
|
397
|
+
if (!hit || hit.row !== e.target) return;
|
|
398
|
+
e.preventDefault();
|
|
399
|
+
toggleSpanRow(hit.trace, hit.row);
|
|
400
|
+
};
|
|
401
|
+
document.addEventListener("click", onClick);
|
|
402
|
+
document.addEventListener("keydown", onKey);
|
|
403
|
+
traceTeardown = () => {
|
|
404
|
+
document.removeEventListener("click", onClick);
|
|
405
|
+
document.removeEventListener("keydown", onKey);
|
|
406
|
+
traceInit = false;
|
|
407
|
+
traceTeardown = null;
|
|
408
|
+
};
|
|
409
|
+
return traceTeardown;
|
|
410
|
+
}
|
|
411
|
+
export {
|
|
412
|
+
initKbTrace,
|
|
413
|
+
renderKbTrace
|
|
414
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { KbVisibility, KbIdentity } from './kb-core.js';
|
|
2
|
+
import './ai-core.js';
|
|
3
|
+
|
|
4
|
+
/** 对照命中的最小数据单元(标题必有;snippet=原文摘录 / summary=AI 摘要,二者权限语义不同) */
|
|
5
|
+
interface KbVisibilityHit {
|
|
6
|
+
id: string;
|
|
7
|
+
title: string;
|
|
8
|
+
/** 原文摘录(visibility=full 时呈现) */
|
|
9
|
+
snippet?: string;
|
|
10
|
+
/** AI 摘要(visibility=summary 时呈现;摘要权限 ≠ 原文权限) */
|
|
11
|
+
summary?: string;
|
|
12
|
+
documentId?: string;
|
|
13
|
+
}
|
|
14
|
+
/** renderKbVisibility 配置项 */
|
|
15
|
+
interface KbVisibilityOpts {
|
|
16
|
+
/** 查询回显(只读展示,不提供输入) */
|
|
17
|
+
query: string;
|
|
18
|
+
/** 对照身份集(固定身份集,spec §9.0-8:来自服务端验证 token,不接受自由输入) */
|
|
19
|
+
identities: KbIdentity[];
|
|
20
|
+
/** 对照命集(各身份列共享同一批行,行的去留由 evaluateHit 决定) */
|
|
21
|
+
hits: KbVisibilityHit[];
|
|
22
|
+
/** 命中×身份 → 可见性五级;缺省全部 'full'(演示语义,真实求值由宿主注入) */
|
|
23
|
+
evaluateHit?: (hit: KbVisibilityHit, identity: KbIdentity) => KbVisibility;
|
|
24
|
+
/** 过滤层徽标初值(缺省 'pre';点击循环 pre→post→none) */
|
|
25
|
+
layer?: 'pre' | 'post' | 'none';
|
|
26
|
+
/** 「申请访问」文字钮回调(宿主接 kb-access 申请流;展示件不派申请事件) */
|
|
27
|
+
onRequest?: (hit: KbVisibilityHit, identity: KbIdentity) => void;
|
|
28
|
+
}
|
|
29
|
+
/** renderKbVisibility 返回的可操作句柄 */
|
|
30
|
+
interface KbVisibilityHandle {
|
|
31
|
+
/** 设置过滤层(重绘徽标并派 icen:kb-visibility-layer {layer}) */
|
|
32
|
+
setFilterLayer(l: 'pre' | 'post' | 'none'): void;
|
|
33
|
+
/** 查询某身份×命中的可见性(查无身份/命中返回 'hidden'——fail-closed,spec §9.0-4) */
|
|
34
|
+
getVisibility(identityUser: string, hitId: string): KbVisibility;
|
|
35
|
+
/** 销毁:摘除监听、清空装配内容、复位幂等标记 */
|
|
36
|
+
destroy(): void;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 渲染检索可见性对照器(admin 审计专用;每身份一列 + 安全计数 + 五级命中行 + 教学段)。
|
|
40
|
+
* 幂等(同元素重复 render 先销毁既有装配);SSR 返回静态 stub;destroy 摘监听并清空。
|
|
41
|
+
*/
|
|
42
|
+
declare function renderKbVisibility(el: HTMLElement, opts: KbVisibilityOpts): KbVisibilityHandle;
|
|
43
|
+
|
|
44
|
+
export { type KbVisibilityHandle, type KbVisibilityHit, type KbVisibilityOpts, renderKbVisibility };
|