@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,403 @@
|
|
|
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
|
+
function svgIcon(svg2) {
|
|
134
|
+
if (typeof document === "undefined" || typeof DOMParser === "undefined") return null;
|
|
135
|
+
let parsed;
|
|
136
|
+
try {
|
|
137
|
+
parsed = new DOMParser().parseFromString(svg2, "image/svg+xml");
|
|
138
|
+
} catch {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
const root = parsed.documentElement;
|
|
142
|
+
if (!root || root.tagName.toLowerCase() !== "svg" || parsed.querySelector("parsererror")) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
const sanitize = (el) => {
|
|
146
|
+
for (const attr of Array.from(el.attributes)) {
|
|
147
|
+
const name = attr.name.toLowerCase();
|
|
148
|
+
if (name.startsWith("on")) el.removeAttribute(attr.name);
|
|
149
|
+
if ((name === "href" || name === "xlink:href") && attr.value.trim().toLowerCase().startsWith("javascript:")) {
|
|
150
|
+
el.removeAttribute(attr.name);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
for (const child of Array.from(el.children)) {
|
|
154
|
+
const tag = child.tagName.toLowerCase();
|
|
155
|
+
if (tag === "script" || tag === "foreignobject") {
|
|
156
|
+
child.remove();
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
sanitize(child);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
sanitize(root);
|
|
163
|
+
return document.importNode(root, true);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// src/behaviors/kb-core.ts
|
|
167
|
+
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>` });
|
|
168
|
+
var BUILTIN_SOURCE_TYPES = {
|
|
169
|
+
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"/>'),
|
|
170
|
+
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"/>'),
|
|
171
|
+
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"/>'),
|
|
172
|
+
sheet: ic("\u8868\u683C", '<rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M3 15h18M9 3v18M15 3v18"/>'),
|
|
173
|
+
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"/>'),
|
|
174
|
+
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"/>'),
|
|
175
|
+
code: ic("\u4EE3\u7801", '<path d="m16 18 6-6-6-6"/><path d="m8 6-6 6 6 6"/>'),
|
|
176
|
+
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"/>'),
|
|
177
|
+
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"/>'),
|
|
178
|
+
mail: ic("\u90AE\u4EF6", '<rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-10 7L2 7"/>')
|
|
179
|
+
};
|
|
180
|
+
var sourceTypeRegistry = new Map(Object.entries(BUILTIN_SOURCE_TYPES));
|
|
181
|
+
function normalizeIdentity(raw) {
|
|
182
|
+
const r = raw;
|
|
183
|
+
return {
|
|
184
|
+
user: String(r.user ?? ""),
|
|
185
|
+
groups: Array.isArray(r.groups) ? r.groups.map(String) : [],
|
|
186
|
+
label: typeof r.label === "string" ? r.label : void 0,
|
|
187
|
+
note: typeof r.note === "string" ? r.note : void 0
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function formatCount(n) {
|
|
191
|
+
if (n == null || !Number.isFinite(n)) return "\u2014";
|
|
192
|
+
if (Math.abs(n) >= 1e4) return `${(n / 1e3).toFixed(1)}k`;
|
|
193
|
+
return n.toLocaleString("en-US");
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// src/behaviors/events.ts
|
|
197
|
+
function emitIcen(source, type, detail) {
|
|
198
|
+
return source.dispatchEvent(
|
|
199
|
+
new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable: true })
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// src/behaviors/kb-citation.ts
|
|
204
|
+
var KB_ICON_LOCK = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="11" x="3" y="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>';
|
|
205
|
+
|
|
206
|
+
// src/behaviors/kb-visibility.ts
|
|
207
|
+
var LAYER_ORDER = ["pre", "post", "none"];
|
|
208
|
+
var LAYER_LABEL = { pre: "pre \u2713", post: "post \u26A0", none: "none \u2715" };
|
|
209
|
+
var LAYER_TITLE = {
|
|
210
|
+
pre: "pre-filter\uFF1AACL \u5728\u68C0\u7D22\u6267\u884C\u4F53\u5185\u751F\u6548\u2014\u2014\u5B89\u5168\u57FA\u7EBF",
|
|
211
|
+
post: "post-filter\uFF1A\u5206\u6570\u5DF2\u53EF\u89C2\u5BDF\u2014\u2014\u7F3A\u9677\u5C42\uFF0C\u4EC5\u6F14\u793A",
|
|
212
|
+
none: "none\uFF1Afail-open\uFF0C\u65E0\u8EAB\u4EFD\u8FC7\u6EE4\u8FD4\u56DE\u5168\u90E8\u2014\u2014\u5371\u9669\uFF0C\u4EC5\u6F14\u793A"
|
|
213
|
+
};
|
|
214
|
+
var LESSON_ITEMS = [
|
|
215
|
+
"fail-open\uFF1AKendra \u65E0\u8EAB\u4EFD\u4E0A\u4E0B\u6587\u8FD4\u56DE\u5168\u90E8\u6587\u6863\u2014\u2014\u68C0\u7D22\u5FC5\u987B\u643A\u5E26\u670D\u52A1\u7AEF\u8EAB\u4EFD",
|
|
216
|
+
"post-filter\uFF1AtopK \u88AB\u65E0\u6743\u7ED3\u679C\u5360\u7528\u4E14\u76F8\u4F3C\u5EA6\u5206\u6570\u53EF\u88AB\u89C2\u5BDF",
|
|
217
|
+
"\u8BA1\u6570\u5DEE\u5F02\u5373 volume leakage\uFF1A\u5BF9\u666E\u901A\u7528\u6237\u53EA\u53EF\u7ED9\u300C\u5DF2\u6309\u6743\u9650\u8FC7\u6EE4\u300D\u6052\u5B9A\u6587\u6848\uFF0C\u7F13\u89E3\u53EA\u6709 padding \u53D6\u6574"
|
|
218
|
+
];
|
|
219
|
+
var STUB_HANDLE = {
|
|
220
|
+
setFilterLayer: () => {
|
|
221
|
+
},
|
|
222
|
+
getVisibility: () => "full",
|
|
223
|
+
destroy: () => {
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
function normalizeHit(raw) {
|
|
227
|
+
const r = raw;
|
|
228
|
+
return {
|
|
229
|
+
id: String(r.id ?? ""),
|
|
230
|
+
title: String(r.title ?? "\u672A\u547D\u540D\u547D\u4E2D"),
|
|
231
|
+
snippet: typeof r.snippet === "string" ? r.snippet : void 0,
|
|
232
|
+
summary: typeof r.summary === "string" ? r.summary : void 0,
|
|
233
|
+
documentId: typeof r.documentId === "string" ? r.documentId : void 0
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function renderKbVisibility(el, opts) {
|
|
237
|
+
if (typeof document === "undefined" || !el) return STUB_HANDLE;
|
|
238
|
+
const marked = el;
|
|
239
|
+
marked.__icenKbVisibility?.destroy();
|
|
240
|
+
const ctrl = new AbortController();
|
|
241
|
+
const listen = (target, type, fn) => {
|
|
242
|
+
target.addEventListener(type, fn, { signal: ctrl.signal });
|
|
243
|
+
};
|
|
244
|
+
const identities = (Array.isArray(opts.identities) ? opts.identities : []).map(normalizeIdentity);
|
|
245
|
+
const hits = (Array.isArray(opts.hits) ? opts.hits : []).map(normalizeHit).filter((hit) => hit.id);
|
|
246
|
+
const evalHit = typeof opts.evaluateHit === "function" ? opts.evaluateHit : () => "full";
|
|
247
|
+
let layer = opts.layer === "post" || opts.layer === "none" ? opts.layer : "pre";
|
|
248
|
+
let focusedUser = null;
|
|
249
|
+
let destroyed = false;
|
|
250
|
+
el.textContent = "";
|
|
251
|
+
el.classList.add("kb-visibility");
|
|
252
|
+
el.appendChild(
|
|
253
|
+
h("div", "kb-visibility-warn", "admin \u5BA1\u8BA1\u89C6\u56FE\u2014\u2014\u547D\u4E2D\u5DEE\u5F02\u5BF9\u7167\u5BF9\u666E\u901A\u7528\u6237\u6784\u6210\u6CC4\u9732\uFF0C\u52FF\u5D4C\u5165\u7EC8\u7AEF\u7528\u6237\u754C\u9762")
|
|
254
|
+
);
|
|
255
|
+
const bar = h("div", "kb-visibility-bar");
|
|
256
|
+
const chipMap = /* @__PURE__ */ new Map();
|
|
257
|
+
for (const identity of identities) {
|
|
258
|
+
const chip = h("button", "kb-chip kb-visibility-idn", identity.label ?? identity.user);
|
|
259
|
+
chip.type = "button";
|
|
260
|
+
chip.dataset.identityUser = identity.user;
|
|
261
|
+
chip.setAttribute("aria-pressed", "false");
|
|
262
|
+
chip.setAttribute("aria-label", `\u805A\u7126\u8EAB\u4EFD ${identity.label ?? identity.user} \u7684\u5217`);
|
|
263
|
+
bar.appendChild(chip);
|
|
264
|
+
chipMap.set(identity.user, chip);
|
|
265
|
+
}
|
|
266
|
+
bar.appendChild(h("span", "kb-meta", `\u67E5\u8BE2\uFF1A${opts.query || "\u2014"}`));
|
|
267
|
+
const layerChip = h("button", "kb-chip kb-layer-chip");
|
|
268
|
+
layerChip.type = "button";
|
|
269
|
+
bar.appendChild(layerChip);
|
|
270
|
+
function paintLayer() {
|
|
271
|
+
layerChip.dataset.layer = layer;
|
|
272
|
+
layerChip.textContent = LAYER_LABEL[layer];
|
|
273
|
+
layerChip.title = LAYER_TITLE[layer];
|
|
274
|
+
layerChip.setAttribute("aria-label", `\u8FC7\u6EE4\u5C42\uFF1A${LAYER_TITLE[layer]}`);
|
|
275
|
+
}
|
|
276
|
+
paintLayer();
|
|
277
|
+
el.appendChild(bar);
|
|
278
|
+
const grid = h("div", "kb-visibility-grid");
|
|
279
|
+
const colMap = /* @__PURE__ */ new Map();
|
|
280
|
+
function buildHitRow(hit, identity) {
|
|
281
|
+
const visibility = evalHit(hit, identity);
|
|
282
|
+
if (visibility === "hidden") return null;
|
|
283
|
+
const row = h("div", "kb-visibility-hit");
|
|
284
|
+
row.dataset.visibility = visibility;
|
|
285
|
+
row.dataset.hitId = hit.id;
|
|
286
|
+
const titleRow = h("div", "kb-visibility-hit-title");
|
|
287
|
+
if (visibility === "metadata" || visibility === "restricted") {
|
|
288
|
+
const lock = svgIcon(KB_ICON_LOCK);
|
|
289
|
+
if (lock) titleRow.appendChild(lock);
|
|
290
|
+
}
|
|
291
|
+
titleRow.appendChild(h("span", "kb-visibility-hit-title-text", hit.title));
|
|
292
|
+
row.appendChild(titleRow);
|
|
293
|
+
if (visibility === "full") {
|
|
294
|
+
if (hit.snippet) row.appendChild(h("div", "kb-visibility-snippet kb-meta", hit.snippet));
|
|
295
|
+
} else if (visibility === "summary") {
|
|
296
|
+
if (hit.summary) row.appendChild(h("div", "kb-visibility-summary", hit.summary));
|
|
297
|
+
const origOff = h("button", "kb-visibility-origoff", "\u539F\u6587\u4E0D\u53EF\u7528");
|
|
298
|
+
origOff.type = "button";
|
|
299
|
+
origOff.disabled = true;
|
|
300
|
+
origOff.setAttribute("aria-disabled", "true");
|
|
301
|
+
row.appendChild(origOff);
|
|
302
|
+
} else {
|
|
303
|
+
row.appendChild(h("div", "kb-visibility-snippet"));
|
|
304
|
+
if (visibility === "restricted") {
|
|
305
|
+
const request = h("button", "kb-visibility-request", "\u7533\u8BF7\u8BBF\u95EE");
|
|
306
|
+
request.type = "button";
|
|
307
|
+
request.setAttribute("aria-label", `\u7533\u8BF7\u8BBF\u95EE ${hit.title}`);
|
|
308
|
+
row.appendChild(request);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return row;
|
|
312
|
+
}
|
|
313
|
+
for (const identity of identities) {
|
|
314
|
+
const col = h("div", "kb-visibility-col");
|
|
315
|
+
col.dataset.identityUser = identity.user;
|
|
316
|
+
const head = h("header");
|
|
317
|
+
head.appendChild(h("span", "kb-visibility-idn-label", identity.label ?? identity.user));
|
|
318
|
+
if (identity.note) head.appendChild(h("span", "kb-meta", identity.note));
|
|
319
|
+
col.appendChild(head);
|
|
320
|
+
let safeCount = 0;
|
|
321
|
+
const hitsBox = h("div", "kb-visibility-hits");
|
|
322
|
+
for (const hit of hits) {
|
|
323
|
+
const row = buildHitRow(hit, identity);
|
|
324
|
+
if (row) {
|
|
325
|
+
hitsBox.appendChild(row);
|
|
326
|
+
safeCount++;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
col.appendChild(h("div", "kb-visibility-count kb-num", `\u5B89\u5168\u8BA1\u6570 ${formatCount(safeCount)}`));
|
|
330
|
+
col.appendChild(hitsBox);
|
|
331
|
+
grid.appendChild(col);
|
|
332
|
+
colMap.set(identity.user, col);
|
|
333
|
+
}
|
|
334
|
+
el.appendChild(grid);
|
|
335
|
+
const lesson = h("div", "kb-visibility-lesson");
|
|
336
|
+
const lessonList = h("ul");
|
|
337
|
+
for (const item of LESSON_ITEMS) lessonList.appendChild(h("li", void 0, item));
|
|
338
|
+
lesson.appendChild(lessonList);
|
|
339
|
+
lesson.appendChild(h("div", "kb-meta kb-visibility-lesson-note", "\u4EE5\u4E0A\u5BF9\u7167\u4EC5\u9650 admin \u5BA1\u8BA1"));
|
|
340
|
+
el.appendChild(lesson);
|
|
341
|
+
function applyLayer(next) {
|
|
342
|
+
if (destroyed || next === layer) return;
|
|
343
|
+
layer = next;
|
|
344
|
+
paintLayer();
|
|
345
|
+
emitIcen(el, "icen:kb-visibility-layer", { layer });
|
|
346
|
+
}
|
|
347
|
+
function setFocus(user) {
|
|
348
|
+
focusedUser = user;
|
|
349
|
+
for (const [u, col] of colMap) col.classList.toggle("is-focused", u === user);
|
|
350
|
+
for (const [u, chip] of chipMap) chip.setAttribute("aria-pressed", u === user ? "true" : "false");
|
|
351
|
+
}
|
|
352
|
+
listen(bar, "click", (ev) => {
|
|
353
|
+
const target = ev.target instanceof Element ? ev.target : null;
|
|
354
|
+
const chip = target?.closest(".kb-visibility-idn");
|
|
355
|
+
if (chip) {
|
|
356
|
+
const user = chip.dataset.identityUser ?? "";
|
|
357
|
+
setFocus(focusedUser === user ? null : user);
|
|
358
|
+
const identity = identities.find((i) => i.user === user);
|
|
359
|
+
if (identity) emitIcen(el, "icen:kb-visibility-identity", { identity });
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
const layerBtn = target?.closest(".kb-layer-chip");
|
|
363
|
+
if (layerBtn) {
|
|
364
|
+
const idx = LAYER_ORDER.indexOf(layer);
|
|
365
|
+
applyLayer(LAYER_ORDER[(idx + 1) % LAYER_ORDER.length]);
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
listen(grid, "click", (ev) => {
|
|
369
|
+
const target = ev.target instanceof Element ? ev.target : null;
|
|
370
|
+
const btn = target?.closest(".kb-visibility-request");
|
|
371
|
+
if (!btn) return;
|
|
372
|
+
const row = btn.closest(".kb-visibility-hit");
|
|
373
|
+
const col = btn.closest(".kb-visibility-col");
|
|
374
|
+
if (!row || !col) return;
|
|
375
|
+
const hit = hits.find((x) => x.id === (row.dataset.hitId ?? ""));
|
|
376
|
+
const identity = identities.find((i) => i.user === (col.dataset.identityUser ?? ""));
|
|
377
|
+
if (hit && identity) opts.onRequest?.(hit, identity);
|
|
378
|
+
});
|
|
379
|
+
const handle = {
|
|
380
|
+
setFilterLayer(l) {
|
|
381
|
+
applyLayer(l === "post" || l === "none" ? l : "pre");
|
|
382
|
+
},
|
|
383
|
+
getVisibility(identityUser, hitId) {
|
|
384
|
+
const identity = identities.find((i) => i.user === identityUser);
|
|
385
|
+
const hit = hits.find((x) => x.id === hitId);
|
|
386
|
+
if (!identity || !hit) return "hidden";
|
|
387
|
+
return evalHit(hit, identity);
|
|
388
|
+
},
|
|
389
|
+
destroy() {
|
|
390
|
+
if (destroyed) return;
|
|
391
|
+
destroyed = true;
|
|
392
|
+
ctrl.abort();
|
|
393
|
+
el.classList.remove("kb-visibility");
|
|
394
|
+
el.textContent = "";
|
|
395
|
+
delete marked.__icenKbVisibility;
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
marked.__icenKbVisibility = handle;
|
|
399
|
+
return handle;
|
|
400
|
+
}
|
|
401
|
+
export {
|
|
402
|
+
renderKbVisibility
|
|
403
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { KbAclDecision, KbIdentity, KbAclEntry } from './kb-core.js';
|
|
2
|
+
import './ai-core.js';
|
|
3
|
+
|
|
4
|
+
/** renderKbWhoCan 配置项 */
|
|
5
|
+
interface KbWhoCanOpts {
|
|
6
|
+
/** 固定身份集(服务端验证 token 下发;select 选项即此集合,无自由输入) */
|
|
7
|
+
identities: KbIdentity[];
|
|
8
|
+
/** 被检查的 ACL 条目集(直接 + 继承 + 链接混排,via 由条目形态推导) */
|
|
9
|
+
entries: KbAclEntry[];
|
|
10
|
+
/** 求值函数(缺省 = kb-core evaluateAcl:先 deny → 并集 → 默认拒绝) */
|
|
11
|
+
evaluate?: (identity: KbIdentity, entries: KbAclEntry[]) => KbAclDecision;
|
|
12
|
+
/** 每次重算回调(与 icen:kb-whocan-check 双通道) */
|
|
13
|
+
onCheck?: (identity: KbIdentity, decision: KbAclDecision) => void;
|
|
14
|
+
}
|
|
15
|
+
/** renderKbWhoCan 返回的可操作句柄 */
|
|
16
|
+
interface KbWhoCanHandle {
|
|
17
|
+
/** 切换检查身份并重算(固定身份集纪律:集合外 id 一律忽略) */
|
|
18
|
+
setIdentity(id: string): void;
|
|
19
|
+
/** 最近一次决策(未重算过/空身份集/SSR → null) */
|
|
20
|
+
getResult(): KbAclDecision | null;
|
|
21
|
+
/** 销毁:摘监听、清空装配内容、复位幂等标记 */
|
|
22
|
+
destroy(): void;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 装配有效权限检查器(view-as):固定身份集下拉 + 检查钮 + 结论区(verdict /
|
|
26
|
+
* deny 置顶红条 / 扁平原因链 / 叠加规则行 / 最近到期 meta)。每次重算派
|
|
27
|
+
* icen:kb-whocan-check { identity, decision }(onCheck 双通道)。
|
|
28
|
+
* 同元素重复 render 幂等(先拆旧装配);SSR 返回静态句柄。
|
|
29
|
+
*/
|
|
30
|
+
declare function renderKbWhoCan(el: HTMLElement, opts: KbWhoCanOpts): KbWhoCanHandle;
|
|
31
|
+
|
|
32
|
+
export { type KbWhoCanHandle, type KbWhoCanOpts, renderKbWhoCan };
|