@elizaos/app-core 2.0.0-alpha.54 → 2.0.0-alpha.55
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/dist/components/AdvancedPageView.d.ts.map +1 -1
- package/dist/components/AdvancedPageView.js +20 -1
- package/dist/components/SecurityPageView.d.ts +2 -0
- package/dist/components/SecurityPageView.d.ts.map +1 -0
- package/dist/components/SecurityPageView.js +81 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/config/config-field.js +1 -1
- package/dist/config/config-renderer.js +1 -1
- package/package.json +4 -4
- package/src/components/AdvancedPageView.tsx +21 -1
- package/src/components/SecurityPageView.tsx +235 -0
- package/src/components/index.ts +1 -0
- package/src/config/config-field.tsx +1 -1
- package/src/config/config-renderer.tsx +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdvancedPageView.d.ts","sourceRoot":"","sources":["../../src/components/AdvancedPageView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"AdvancedPageView.d.ts","sourceRoot":"","sources":["../../src/components/AdvancedPageView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAqPH,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,2CA4HvE"}
|
|
@@ -18,9 +18,15 @@ import { useState } from "react";
|
|
|
18
18
|
import { CustomActionsView } from "./CustomActionsView";
|
|
19
19
|
import { FineTuningView } from "./FineTuningView";
|
|
20
20
|
import { LifoSandboxView } from "./LifoSandboxView";
|
|
21
|
+
import { SecurityPageView } from "./SecurityPageView";
|
|
21
22
|
import { TrajectoriesView } from "./TrajectoriesView";
|
|
22
23
|
import { TrajectoryDetailView } from "./TrajectoryDetailView";
|
|
23
24
|
const SUB_TABS = [
|
|
25
|
+
{
|
|
26
|
+
id: "actions",
|
|
27
|
+
label: "Actions",
|
|
28
|
+
description: "Custom agent commands and workflows",
|
|
29
|
+
},
|
|
24
30
|
{ id: "plugins", label: "Plugins", description: "Features and connectors" },
|
|
25
31
|
{ id: "skills", label: "Skills", description: "Custom agent skills" },
|
|
26
32
|
// {
|
|
@@ -49,6 +55,11 @@ const SUB_TABS = [
|
|
|
49
55
|
// description: "Browser-native shell sandbox and file explorer",
|
|
50
56
|
// },
|
|
51
57
|
{ id: "logs", label: "Logs", description: "Runtime and service logs" },
|
|
58
|
+
{
|
|
59
|
+
id: "security",
|
|
60
|
+
label: "Security",
|
|
61
|
+
description: "Audit trail for privileged runtime activity",
|
|
62
|
+
},
|
|
52
63
|
];
|
|
53
64
|
const MODAL_SUB_TABS = SUB_TABS.filter((t) => t.id !== "plugins" && t.id !== "skills");
|
|
54
65
|
const SUBTAB_ICONS = {
|
|
@@ -63,6 +74,8 @@ const SUBTAB_ICONS = {
|
|
|
63
74
|
};
|
|
64
75
|
function mapTabToSubTab(tab) {
|
|
65
76
|
switch (tab) {
|
|
77
|
+
case "actions":
|
|
78
|
+
return "actions";
|
|
66
79
|
case "plugins":
|
|
67
80
|
return "plugins";
|
|
68
81
|
case "skills":
|
|
@@ -79,6 +92,8 @@ function mapTabToSubTab(tab) {
|
|
|
79
92
|
return "lifo";
|
|
80
93
|
case "logs":
|
|
81
94
|
return "logs";
|
|
95
|
+
case "security":
|
|
96
|
+
return "security";
|
|
82
97
|
default:
|
|
83
98
|
return "plugins";
|
|
84
99
|
}
|
|
@@ -94,6 +109,8 @@ export function AdvancedPageView({ inModal } = {}) {
|
|
|
94
109
|
};
|
|
95
110
|
const renderContent = () => {
|
|
96
111
|
switch (currentSubTab) {
|
|
112
|
+
case "actions":
|
|
113
|
+
return _jsx(CustomActionsView, {});
|
|
97
114
|
case "plugins":
|
|
98
115
|
return _jsx(PluginsPageView, {});
|
|
99
116
|
case "skills":
|
|
@@ -113,8 +130,10 @@ export function AdvancedPageView({ inModal } = {}) {
|
|
|
113
130
|
return _jsx(LifoSandboxView, {});
|
|
114
131
|
case "logs":
|
|
115
132
|
return _jsx(LogsPageView, {});
|
|
133
|
+
case "security":
|
|
134
|
+
return _jsx(SecurityPageView, {});
|
|
116
135
|
default:
|
|
117
|
-
return
|
|
136
|
+
return _jsx(PluginsPageView, {});
|
|
118
137
|
}
|
|
119
138
|
};
|
|
120
139
|
return (_jsxs("div", { className: inModal ? "settings-modal-layout" : "flex flex-col h-full min-h-0", children: [inModal ? (_jsx("nav", { className: "settings-icon-sidebar", children: tabs.map((subTab) => (_jsxs("button", { type: "button", className: `advanced-subtab-btn settings-icon-btn ${currentSubTab === subTab.id ? "is-active" : ""}`, onClick: () => handleSubTabChange(subTab.id), title: subTab.description, children: [SUBTAB_ICONS[subTab.id], _jsx("span", { className: "settings-icon-label", children: subTab.label })] }, subTab.id))) })) : (_jsx("div", { className: "mb-4 shrink-0", children: _jsx("div", { className: "flex gap-1 border-b border-border", children: tabs.map((subTab) => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SecurityPageView.d.ts","sourceRoot":"","sources":["../../src/components/SecurityPageView.tsx"],"names":[],"mappings":"AAgEA,wBAAgB,gBAAgB,4CA0K/B"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from "@elizaos/ui";
|
|
3
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
4
|
+
import { client, } from "../api";
|
|
5
|
+
import { formatDateTime } from "./format";
|
|
6
|
+
const SEVERITY_OPTIONS = [
|
|
7
|
+
{ value: "", label: "All severities" },
|
|
8
|
+
{ value: "critical", label: "Critical" },
|
|
9
|
+
{ value: "error", label: "Error" },
|
|
10
|
+
{ value: "warn", label: "Warn" },
|
|
11
|
+
{ value: "info", label: "Info" },
|
|
12
|
+
];
|
|
13
|
+
const SEVERITY_STYLES = {
|
|
14
|
+
critical: {
|
|
15
|
+
badge: "bg-red-500/15 text-red-300 border-red-500/30",
|
|
16
|
+
tone: "text-red-200",
|
|
17
|
+
},
|
|
18
|
+
error: {
|
|
19
|
+
badge: "bg-orange-500/15 text-orange-200 border-orange-500/30",
|
|
20
|
+
tone: "text-orange-100",
|
|
21
|
+
},
|
|
22
|
+
warn: {
|
|
23
|
+
badge: "bg-amber-500/15 text-amber-200 border-amber-500/30",
|
|
24
|
+
tone: "text-amber-100",
|
|
25
|
+
},
|
|
26
|
+
info: {
|
|
27
|
+
badge: "bg-sky-500/15 text-sky-200 border-sky-500/30",
|
|
28
|
+
tone: "text-sky-100",
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
function summarizeCounts(entries) {
|
|
32
|
+
return entries.reduce((counts, entry) => {
|
|
33
|
+
counts[entry.severity] += 1;
|
|
34
|
+
return counts;
|
|
35
|
+
}, {
|
|
36
|
+
critical: 0,
|
|
37
|
+
error: 0,
|
|
38
|
+
warn: 0,
|
|
39
|
+
info: 0,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function metadataPairs(entry) {
|
|
43
|
+
return Object.entries(entry.metadata ?? {}).map(([key, value]) => [
|
|
44
|
+
key,
|
|
45
|
+
String(value),
|
|
46
|
+
]);
|
|
47
|
+
}
|
|
48
|
+
export function SecurityPageView() {
|
|
49
|
+
const [entries, setEntries] = useState([]);
|
|
50
|
+
const [totalBuffered, setTotalBuffered] = useState(0);
|
|
51
|
+
const [severity, setSeverity] = useState("");
|
|
52
|
+
const [loading, setLoading] = useState(true);
|
|
53
|
+
const [error, setError] = useState(null);
|
|
54
|
+
const loadAudit = useCallback(async () => {
|
|
55
|
+
setLoading(true);
|
|
56
|
+
setError(null);
|
|
57
|
+
try {
|
|
58
|
+
const response = await client.getSecurityAudit({
|
|
59
|
+
limit: 50,
|
|
60
|
+
severity: severity || undefined,
|
|
61
|
+
});
|
|
62
|
+
setEntries(response.entries);
|
|
63
|
+
setTotalBuffered(response.totalBuffered);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
setError(err instanceof Error ? err.message : "Failed to load audit log.");
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
setLoading(false);
|
|
70
|
+
}
|
|
71
|
+
}, [severity]);
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
void loadAudit();
|
|
74
|
+
}, [loadAudit]);
|
|
75
|
+
const counts = useMemo(() => summarizeCounts(entries), [entries]);
|
|
76
|
+
return (_jsxs("section", { className: "flex h-full flex-col gap-4", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsx("h2", { className: "m-0 text-lg font-bold", children: "Security Audit" }), _jsx("p", { className: "mt-1 text-sm text-[var(--muted)]", children: "Review privileged actions, policy decisions, and runtime security events." })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("select", { "aria-label": "Security severity filter", className: "h-9 min-w-40 rounded-xl border border-border bg-bg px-3 text-sm text-txt", value: severity, onChange: (event) => setSeverity(event.target.value), children: SEVERITY_OPTIONS.map((option) => (_jsx("option", { value: option.value, children: option.label }, option.label))) }), _jsx(Button, { type: "button", variant: "outline", size: "sm", className: "h-9 rounded-xl", onClick: () => void loadAudit(), disabled: loading, children: loading ? "Refreshing..." : "Refresh" })] })] }), _jsxs("div", { className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-5", children: [_jsxs("div", { className: "rounded-2xl border border-border/60 bg-card/50 p-4", children: [_jsx("div", { className: "text-xs uppercase tracking-[0.16em] text-muted", children: "Buffered" }), _jsx("div", { className: "mt-2 text-2xl font-semibold", children: totalBuffered })] }), ["critical", "error", "warn", "info"].map((level) => (_jsxs("div", { className: "rounded-2xl border border-border/60 bg-card/50 p-4", children: [_jsx("div", { className: "text-xs uppercase tracking-[0.16em] text-muted", children: level }), _jsx("div", { className: `mt-2 text-2xl font-semibold ${SEVERITY_STYLES[level].tone}`, children: counts[level] })] }, level)))] }), error ? (_jsx("div", { className: "rounded-2xl border border-red-500/30 bg-red-500/10 px-4 py-3 text-sm text-red-200", children: error })) : null, _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto rounded-2xl border border-border/60 bg-card/35", children: loading && entries.length === 0 ? (_jsx("div", { className: "px-4 py-6 text-sm text-[var(--muted)]", children: "Loading security audit..." })) : entries.length === 0 ? (_jsx("div", { className: "px-4 py-6 text-sm text-[var(--muted)]", children: "No security events recorded for the current filter." })) : (_jsx("div", { className: "divide-y divide-border/50", children: entries.map((entry, index) => {
|
|
77
|
+
const metadata = metadataPairs(entry);
|
|
78
|
+
const severityStyle = SEVERITY_STYLES[entry.severity];
|
|
79
|
+
return (_jsxs("article", { className: "px-4 py-4", children: [_jsxs("div", { className: "flex flex-wrap items-start gap-3", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: `rounded-full border px-2 py-0.5 text-[11px] font-semibold uppercase tracking-[0.14em] ${severityStyle.badge}`, children: entry.severity }), _jsx("span", { className: "text-xs text-[var(--muted)]", children: entry.type })] }), _jsx("div", { className: "mt-2 text-sm font-medium text-txt", children: entry.summary })] }), _jsx("div", { className: "text-right text-xs text-[var(--muted)]", children: formatDateTime(entry.timestamp) })] }), entry.traceId ? (_jsxs("div", { className: "mt-2 text-xs text-[var(--muted)]", children: ["Trace:", " ", _jsx("span", { className: "font-mono text-txt", children: entry.traceId })] })) : null, metadata.length > 0 ? (_jsx("dl", { className: "mt-3 grid gap-2 sm:grid-cols-2 xl:grid-cols-3", children: metadata.map(([key, value]) => (_jsxs("div", { className: "rounded-xl border border-border/40 bg-bg/40 px-3 py-2", children: [_jsx("dt", { className: "text-[11px] uppercase tracking-[0.12em] text-muted", children: key }), _jsx("dd", { className: "mt-1 break-all font-mono text-xs text-txt", children: value })] }, `${entry.timestamp}-${key}`))) })) : null] }, `${entry.timestamp}-${entry.type}-${index}`));
|
|
80
|
+
}) })) })] }));
|
|
81
|
+
}
|
|
@@ -71,6 +71,7 @@ export * from "./RestartBanner";
|
|
|
71
71
|
export * from "./RuntimeView";
|
|
72
72
|
export * from "./SaveCommandModal";
|
|
73
73
|
export * from "./SecretsView";
|
|
74
|
+
export * from "./SecurityPageView";
|
|
74
75
|
export * from "./SettingsView";
|
|
75
76
|
export * from "./ShellOverlays";
|
|
76
77
|
export * from "./ShortcutsOverlay";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
|
package/dist/components/index.js
CHANGED
|
@@ -71,6 +71,7 @@ export * from "./RestartBanner";
|
|
|
71
71
|
export * from "./RuntimeView";
|
|
72
72
|
export * from "./SaveCommandModal";
|
|
73
73
|
export * from "./SecretsView";
|
|
74
|
+
export * from "./SecurityPageView";
|
|
74
75
|
export * from "./SettingsView";
|
|
75
76
|
export * from "./ShellOverlays";
|
|
76
77
|
export * from "./ShortcutsOverlay";
|
|
@@ -11,7 +11,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
11
11
|
*/
|
|
12
12
|
import { ChevronDown, X } from "lucide-react";
|
|
13
13
|
import React, { useCallback, useRef, useState } from "react";
|
|
14
|
-
import { useApp } from "../state";
|
|
14
|
+
import { useApp } from "../state/useApp";
|
|
15
15
|
import { resolveDynamic } from "./config-catalog";
|
|
16
16
|
// ── Action binding helper ──────────────────────────────────────────────
|
|
17
17
|
/**
|
|
@@ -12,7 +12,7 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
|
12
12
|
* - Prompt generation: registry.catalog.prompt() for AI system prompts
|
|
13
13
|
*/
|
|
14
14
|
import React, { forwardRef, useCallback, useImperativeHandle, useMemo, useState, } from "react";
|
|
15
|
-
import { useApp } from "../state";
|
|
15
|
+
import { useApp } from "../state/useApp";
|
|
16
16
|
import { defaultCatalog, defineRegistry, evaluateShowIf, evaluateVisibility, resolveFields, runValidation, } from "./config-catalog";
|
|
17
17
|
import { ConfigField } from "./config-field";
|
|
18
18
|
// ── Group icons ────────────────────────────────────────────────────────
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elizaos/app-core",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.55",
|
|
4
4
|
"description": "Shared application core for elizaOS shells and white-label apps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
"@capacitor/haptics": "8.0.0",
|
|
69
69
|
"@capacitor/keyboard": "8.0.0",
|
|
70
70
|
"@capacitor/preferences": "^8.0.1",
|
|
71
|
-
"@elizaos/autonomous": "2.0.0-alpha.
|
|
72
|
-
"@elizaos/ui": "2.0.0-alpha.
|
|
71
|
+
"@elizaos/autonomous": "2.0.0-alpha.55",
|
|
72
|
+
"@elizaos/ui": "2.0.0-alpha.55",
|
|
73
73
|
"@lifo-sh/core": "0.4.4",
|
|
74
74
|
"@lifo-sh/ui": "0.4.2",
|
|
75
75
|
"@pixiv/three-vrm": "^3.4.5",
|
|
@@ -89,5 +89,5 @@
|
|
|
89
89
|
"tailwindcss": "^4.1.18",
|
|
90
90
|
"typescript": "^5.9.3"
|
|
91
91
|
},
|
|
92
|
-
"gitHead": "
|
|
92
|
+
"gitHead": "500b9377b46e9e674d0624b4e964bfd10ae7d9d8"
|
|
93
93
|
}
|
|
@@ -25,10 +25,12 @@ import React, { type ReactNode, useState } from "react";
|
|
|
25
25
|
import { CustomActionsView } from "./CustomActionsView";
|
|
26
26
|
import { FineTuningView } from "./FineTuningView";
|
|
27
27
|
import { LifoSandboxView } from "./LifoSandboxView";
|
|
28
|
+
import { SecurityPageView } from "./SecurityPageView";
|
|
28
29
|
import { TrajectoriesView } from "./TrajectoriesView";
|
|
29
30
|
import { TrajectoryDetailView } from "./TrajectoryDetailView";
|
|
30
31
|
|
|
31
32
|
type SubTab =
|
|
33
|
+
| "actions"
|
|
32
34
|
| "plugins"
|
|
33
35
|
| "skills"
|
|
34
36
|
| "fine-tuning"
|
|
@@ -40,6 +42,11 @@ type SubTab =
|
|
|
40
42
|
| "security";
|
|
41
43
|
|
|
42
44
|
const SUB_TABS: Array<{ id: SubTab; label: string; description: string }> = [
|
|
45
|
+
{
|
|
46
|
+
id: "actions",
|
|
47
|
+
label: "Actions",
|
|
48
|
+
description: "Custom agent commands and workflows",
|
|
49
|
+
},
|
|
43
50
|
{ id: "plugins", label: "Plugins", description: "Features and connectors" },
|
|
44
51
|
{ id: "skills", label: "Skills", description: "Custom agent skills" },
|
|
45
52
|
// {
|
|
@@ -68,6 +75,11 @@ const SUB_TABS: Array<{ id: SubTab; label: string; description: string }> = [
|
|
|
68
75
|
// description: "Browser-native shell sandbox and file explorer",
|
|
69
76
|
// },
|
|
70
77
|
{ id: "logs", label: "Logs", description: "Runtime and service logs" },
|
|
78
|
+
{
|
|
79
|
+
id: "security",
|
|
80
|
+
label: "Security",
|
|
81
|
+
description: "Audit trail for privileged runtime activity",
|
|
82
|
+
},
|
|
71
83
|
];
|
|
72
84
|
|
|
73
85
|
const MODAL_SUB_TABS = SUB_TABS.filter(
|
|
@@ -218,6 +230,8 @@ const SUBTAB_ICONS: Record<string, ReactNode> = {
|
|
|
218
230
|
|
|
219
231
|
function mapTabToSubTab(tab: Tab): SubTab {
|
|
220
232
|
switch (tab) {
|
|
233
|
+
case "actions":
|
|
234
|
+
return "actions";
|
|
221
235
|
case "plugins":
|
|
222
236
|
return "plugins";
|
|
223
237
|
case "skills":
|
|
@@ -234,6 +248,8 @@ function mapTabToSubTab(tab: Tab): SubTab {
|
|
|
234
248
|
return "lifo";
|
|
235
249
|
case "logs":
|
|
236
250
|
return "logs";
|
|
251
|
+
case "security":
|
|
252
|
+
return "security";
|
|
237
253
|
default:
|
|
238
254
|
return "plugins";
|
|
239
255
|
}
|
|
@@ -255,6 +271,8 @@ export function AdvancedPageView({ inModal }: { inModal?: boolean } = {}) {
|
|
|
255
271
|
|
|
256
272
|
const renderContent = () => {
|
|
257
273
|
switch (currentSubTab) {
|
|
274
|
+
case "actions":
|
|
275
|
+
return <CustomActionsView />;
|
|
258
276
|
case "plugins":
|
|
259
277
|
return <PluginsPageView />;
|
|
260
278
|
case "skills":
|
|
@@ -281,8 +299,10 @@ export function AdvancedPageView({ inModal }: { inModal?: boolean } = {}) {
|
|
|
281
299
|
return <LifoSandboxView />;
|
|
282
300
|
case "logs":
|
|
283
301
|
return <LogsPageView />;
|
|
302
|
+
case "security":
|
|
303
|
+
return <SecurityPageView />;
|
|
284
304
|
default:
|
|
285
|
-
return
|
|
305
|
+
return <PluginsPageView />;
|
|
286
306
|
}
|
|
287
307
|
};
|
|
288
308
|
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { Button } from "@elizaos/ui";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
3
|
+
import {
|
|
4
|
+
client,
|
|
5
|
+
type SecurityAuditEntry,
|
|
6
|
+
type SecurityAuditSeverity,
|
|
7
|
+
} from "../api";
|
|
8
|
+
import { formatDateTime } from "./format";
|
|
9
|
+
|
|
10
|
+
const SEVERITY_OPTIONS: Array<{
|
|
11
|
+
value: "" | SecurityAuditSeverity;
|
|
12
|
+
label: string;
|
|
13
|
+
}> = [
|
|
14
|
+
{ value: "", label: "All severities" },
|
|
15
|
+
{ value: "critical", label: "Critical" },
|
|
16
|
+
{ value: "error", label: "Error" },
|
|
17
|
+
{ value: "warn", label: "Warn" },
|
|
18
|
+
{ value: "info", label: "Info" },
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const SEVERITY_STYLES: Record<
|
|
22
|
+
SecurityAuditSeverity,
|
|
23
|
+
{ badge: string; tone: string }
|
|
24
|
+
> = {
|
|
25
|
+
critical: {
|
|
26
|
+
badge: "bg-red-500/15 text-red-300 border-red-500/30",
|
|
27
|
+
tone: "text-red-200",
|
|
28
|
+
},
|
|
29
|
+
error: {
|
|
30
|
+
badge: "bg-orange-500/15 text-orange-200 border-orange-500/30",
|
|
31
|
+
tone: "text-orange-100",
|
|
32
|
+
},
|
|
33
|
+
warn: {
|
|
34
|
+
badge: "bg-amber-500/15 text-amber-200 border-amber-500/30",
|
|
35
|
+
tone: "text-amber-100",
|
|
36
|
+
},
|
|
37
|
+
info: {
|
|
38
|
+
badge: "bg-sky-500/15 text-sky-200 border-sky-500/30",
|
|
39
|
+
tone: "text-sky-100",
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
function summarizeCounts(entries: SecurityAuditEntry[]) {
|
|
44
|
+
return entries.reduce<Record<SecurityAuditSeverity, number>>(
|
|
45
|
+
(counts, entry) => {
|
|
46
|
+
counts[entry.severity] += 1;
|
|
47
|
+
return counts;
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
critical: 0,
|
|
51
|
+
error: 0,
|
|
52
|
+
warn: 0,
|
|
53
|
+
info: 0,
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function metadataPairs(entry: SecurityAuditEntry): Array<[string, string]> {
|
|
59
|
+
return Object.entries(entry.metadata ?? {}).map(([key, value]) => [
|
|
60
|
+
key,
|
|
61
|
+
String(value),
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function SecurityPageView() {
|
|
66
|
+
const [entries, setEntries] = useState<SecurityAuditEntry[]>([]);
|
|
67
|
+
const [totalBuffered, setTotalBuffered] = useState(0);
|
|
68
|
+
const [severity, setSeverity] = useState<"" | SecurityAuditSeverity>("");
|
|
69
|
+
const [loading, setLoading] = useState(true);
|
|
70
|
+
const [error, setError] = useState<string | null>(null);
|
|
71
|
+
|
|
72
|
+
const loadAudit = useCallback(async () => {
|
|
73
|
+
setLoading(true);
|
|
74
|
+
setError(null);
|
|
75
|
+
try {
|
|
76
|
+
const response = await client.getSecurityAudit({
|
|
77
|
+
limit: 50,
|
|
78
|
+
severity: severity || undefined,
|
|
79
|
+
});
|
|
80
|
+
setEntries(response.entries);
|
|
81
|
+
setTotalBuffered(response.totalBuffered);
|
|
82
|
+
} catch (err) {
|
|
83
|
+
setError(err instanceof Error ? err.message : "Failed to load audit log.");
|
|
84
|
+
} finally {
|
|
85
|
+
setLoading(false);
|
|
86
|
+
}
|
|
87
|
+
}, [severity]);
|
|
88
|
+
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
void loadAudit();
|
|
91
|
+
}, [loadAudit]);
|
|
92
|
+
|
|
93
|
+
const counts = useMemo(() => summarizeCounts(entries), [entries]);
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<section className="flex h-full flex-col gap-4">
|
|
97
|
+
<div className="flex flex-wrap items-start justify-between gap-3">
|
|
98
|
+
<div>
|
|
99
|
+
<h2 className="m-0 text-lg font-bold">Security Audit</h2>
|
|
100
|
+
<p className="mt-1 text-sm text-[var(--muted)]">
|
|
101
|
+
Review privileged actions, policy decisions, and runtime security
|
|
102
|
+
events.
|
|
103
|
+
</p>
|
|
104
|
+
</div>
|
|
105
|
+
<div className="flex items-center gap-2">
|
|
106
|
+
<select
|
|
107
|
+
aria-label="Security severity filter"
|
|
108
|
+
className="h-9 min-w-40 rounded-xl border border-border bg-bg px-3 text-sm text-txt"
|
|
109
|
+
value={severity}
|
|
110
|
+
onChange={(event) =>
|
|
111
|
+
setSeverity(event.target.value as "" | SecurityAuditSeverity)
|
|
112
|
+
}
|
|
113
|
+
>
|
|
114
|
+
{SEVERITY_OPTIONS.map((option) => (
|
|
115
|
+
<option key={option.label} value={option.value}>
|
|
116
|
+
{option.label}
|
|
117
|
+
</option>
|
|
118
|
+
))}
|
|
119
|
+
</select>
|
|
120
|
+
<Button
|
|
121
|
+
type="button"
|
|
122
|
+
variant="outline"
|
|
123
|
+
size="sm"
|
|
124
|
+
className="h-9 rounded-xl"
|
|
125
|
+
onClick={() => void loadAudit()}
|
|
126
|
+
disabled={loading}
|
|
127
|
+
>
|
|
128
|
+
{loading ? "Refreshing..." : "Refresh"}
|
|
129
|
+
</Button>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-5">
|
|
134
|
+
<div className="rounded-2xl border border-border/60 bg-card/50 p-4">
|
|
135
|
+
<div className="text-xs uppercase tracking-[0.16em] text-muted">
|
|
136
|
+
Buffered
|
|
137
|
+
</div>
|
|
138
|
+
<div className="mt-2 text-2xl font-semibold">{totalBuffered}</div>
|
|
139
|
+
</div>
|
|
140
|
+
{(["critical", "error", "warn", "info"] as const).map((level) => (
|
|
141
|
+
<div
|
|
142
|
+
key={level}
|
|
143
|
+
className="rounded-2xl border border-border/60 bg-card/50 p-4"
|
|
144
|
+
>
|
|
145
|
+
<div className="text-xs uppercase tracking-[0.16em] text-muted">
|
|
146
|
+
{level}
|
|
147
|
+
</div>
|
|
148
|
+
<div
|
|
149
|
+
className={`mt-2 text-2xl font-semibold ${SEVERITY_STYLES[level].tone}`}
|
|
150
|
+
>
|
|
151
|
+
{counts[level]}
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
))}
|
|
155
|
+
</div>
|
|
156
|
+
|
|
157
|
+
{error ? (
|
|
158
|
+
<div className="rounded-2xl border border-red-500/30 bg-red-500/10 px-4 py-3 text-sm text-red-200">
|
|
159
|
+
{error}
|
|
160
|
+
</div>
|
|
161
|
+
) : null}
|
|
162
|
+
|
|
163
|
+
<div className="min-h-0 flex-1 overflow-y-auto rounded-2xl border border-border/60 bg-card/35">
|
|
164
|
+
{loading && entries.length === 0 ? (
|
|
165
|
+
<div className="px-4 py-6 text-sm text-[var(--muted)]">
|
|
166
|
+
Loading security audit...
|
|
167
|
+
</div>
|
|
168
|
+
) : entries.length === 0 ? (
|
|
169
|
+
<div className="px-4 py-6 text-sm text-[var(--muted)]">
|
|
170
|
+
No security events recorded for the current filter.
|
|
171
|
+
</div>
|
|
172
|
+
) : (
|
|
173
|
+
<div className="divide-y divide-border/50">
|
|
174
|
+
{entries.map((entry, index) => {
|
|
175
|
+
const metadata = metadataPairs(entry);
|
|
176
|
+
const severityStyle = SEVERITY_STYLES[entry.severity];
|
|
177
|
+
return (
|
|
178
|
+
<article
|
|
179
|
+
key={`${entry.timestamp}-${entry.type}-${index}`}
|
|
180
|
+
className="px-4 py-4"
|
|
181
|
+
>
|
|
182
|
+
<div className="flex flex-wrap items-start gap-3">
|
|
183
|
+
<div className="min-w-0 flex-1">
|
|
184
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
185
|
+
<span
|
|
186
|
+
className={`rounded-full border px-2 py-0.5 text-[11px] font-semibold uppercase tracking-[0.14em] ${severityStyle.badge}`}
|
|
187
|
+
>
|
|
188
|
+
{entry.severity}
|
|
189
|
+
</span>
|
|
190
|
+
<span className="text-xs text-[var(--muted)]">
|
|
191
|
+
{entry.type}
|
|
192
|
+
</span>
|
|
193
|
+
</div>
|
|
194
|
+
<div className="mt-2 text-sm font-medium text-txt">
|
|
195
|
+
{entry.summary}
|
|
196
|
+
</div>
|
|
197
|
+
</div>
|
|
198
|
+
<div className="text-right text-xs text-[var(--muted)]">
|
|
199
|
+
{formatDateTime(entry.timestamp)}
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
{entry.traceId ? (
|
|
204
|
+
<div className="mt-2 text-xs text-[var(--muted)]">
|
|
205
|
+
Trace:{" "}
|
|
206
|
+
<span className="font-mono text-txt">{entry.traceId}</span>
|
|
207
|
+
</div>
|
|
208
|
+
) : null}
|
|
209
|
+
|
|
210
|
+
{metadata.length > 0 ? (
|
|
211
|
+
<dl className="mt-3 grid gap-2 sm:grid-cols-2 xl:grid-cols-3">
|
|
212
|
+
{metadata.map(([key, value]) => (
|
|
213
|
+
<div
|
|
214
|
+
key={`${entry.timestamp}-${key}`}
|
|
215
|
+
className="rounded-xl border border-border/40 bg-bg/40 px-3 py-2"
|
|
216
|
+
>
|
|
217
|
+
<dt className="text-[11px] uppercase tracking-[0.12em] text-muted">
|
|
218
|
+
{key}
|
|
219
|
+
</dt>
|
|
220
|
+
<dd className="mt-1 break-all font-mono text-xs text-txt">
|
|
221
|
+
{value}
|
|
222
|
+
</dd>
|
|
223
|
+
</div>
|
|
224
|
+
))}
|
|
225
|
+
</dl>
|
|
226
|
+
) : null}
|
|
227
|
+
</article>
|
|
228
|
+
);
|
|
229
|
+
})}
|
|
230
|
+
</div>
|
|
231
|
+
)}
|
|
232
|
+
</div>
|
|
233
|
+
</section>
|
|
234
|
+
);
|
|
235
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -71,6 +71,7 @@ export * from "./RestartBanner";
|
|
|
71
71
|
export * from "./RuntimeView";
|
|
72
72
|
export * from "./SaveCommandModal";
|
|
73
73
|
export * from "./SecretsView";
|
|
74
|
+
export * from "./SecurityPageView";
|
|
74
75
|
export * from "./SettingsView";
|
|
75
76
|
export * from "./ShellOverlays";
|
|
76
77
|
export * from "./ShortcutsOverlay";
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import { ChevronDown, X } from "lucide-react";
|
|
13
13
|
import React, { useCallback, useRef, useState } from "react";
|
|
14
|
-
import { useApp } from "../state";
|
|
14
|
+
import { useApp } from "../state/useApp";
|
|
15
15
|
import type { DynamicValue } from "../types";
|
|
16
16
|
import type { FieldRenderer, FieldRenderProps } from "./config-catalog";
|
|
17
17
|
import { resolveDynamic } from "./config-catalog";
|