@chrysb/alphaclaw 0.8.1-beta.8 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -24
- package/bin/alphaclaw.js +13 -2
- package/lib/public/css/tailwind.generated.css +1 -0
- package/lib/public/css/tailwind.input.css +3 -0
- package/lib/public/css/theme.css +28 -0
- package/lib/public/css/vendor/xterm.css +218 -0
- package/lib/public/dist/app.bundle.js +10514 -0
- package/lib/public/dist/chunks/addon-fit-W4YZGRNV.js +1 -0
- package/lib/public/dist/chunks/chunk-72ZECFVW.js +1 -0
- package/lib/public/dist/chunks/xterm-KOX4YMOF.js +9 -0
- package/lib/public/js/app.js +4 -4
- package/lib/public/js/components/action-button.js +8 -8
- package/lib/public/js/components/add-channel-menu.js +2 -2
- package/lib/public/js/components/agent-send-modal.js +6 -6
- package/lib/public/js/components/agents-tab/agent-bindings-section/channel-item-trailing.js +7 -7
- package/lib/public/js/components/agents-tab/agent-bindings-section/index.js +3 -3
- package/lib/public/js/components/agents-tab/agent-bindings-section/use-agent-bindings.js +1 -1
- package/lib/public/js/components/agents-tab/agent-bindings-section/use-channel-items.js +4 -4
- package/lib/public/js/components/agents-tab/agent-detail-panel.js +5 -5
- package/lib/public/js/components/agents-tab/agent-identity-section.js +18 -18
- package/lib/public/js/components/agents-tab/agent-overview/index.js +2 -2
- package/lib/public/js/components/agents-tab/agent-overview/manage-card.js +2 -2
- package/lib/public/js/components/agents-tab/agent-overview/model-card.js +8 -8
- package/lib/public/js/components/agents-tab/agent-overview/tools-card.js +5 -5
- package/lib/public/js/components/agents-tab/agent-overview/use-model-card.js +1 -1
- package/lib/public/js/components/agents-tab/agent-overview/use-workspace-card.js +1 -1
- package/lib/public/js/components/agents-tab/agent-overview/workspace-card.js +4 -4
- package/lib/public/js/components/agents-tab/agent-pairing-section.js +4 -4
- package/lib/public/js/components/agents-tab/agent-tools/index.js +5 -5
- package/lib/public/js/components/agents-tab/agent-tools/use-agent-tools.js +1 -1
- package/lib/public/js/components/agents-tab/create-agent-modal.js +13 -13
- package/lib/public/js/components/agents-tab/create-channel-modal.js +34 -34
- package/lib/public/js/components/agents-tab/delete-agent-dialog.js +3 -3
- package/lib/public/js/components/agents-tab/edit-agent-modal.js +9 -9
- package/lib/public/js/components/agents-tab/index.js +3 -3
- package/lib/public/js/components/agents-tab/use-agents.js +1 -1
- package/lib/public/js/components/badge.js +6 -6
- package/lib/public/js/components/channel-account-status-badge.js +2 -2
- package/lib/public/js/components/channel-operations-panel.js +2 -2
- package/lib/public/js/components/channels.js +9 -9
- package/lib/public/js/components/confirm-dialog.js +5 -5
- package/lib/public/js/components/credentials-modal.js +22 -22
- package/lib/public/js/components/cron-tab/cron-calendar.js +6 -6
- package/lib/public/js/components/cron-tab/cron-insights-panel.js +10 -10
- package/lib/public/js/components/cron-tab/cron-job-detail.js +4 -4
- package/lib/public/js/components/cron-tab/cron-job-list.js +4 -4
- package/lib/public/js/components/cron-tab/cron-job-settings-card.js +15 -15
- package/lib/public/js/components/cron-tab/cron-job-trends-panel.js +5 -5
- package/lib/public/js/components/cron-tab/cron-job-usage.js +16 -16
- package/lib/public/js/components/cron-tab/cron-overview.js +10 -10
- package/lib/public/js/components/cron-tab/cron-prompt-editor.js +3 -3
- package/lib/public/js/components/cron-tab/cron-run-history-panel.js +39 -39
- package/lib/public/js/components/cron-tab/cron-runs-trend-card.js +4 -4
- package/lib/public/js/components/cron-tab/index.js +5 -5
- package/lib/public/js/components/cron-tab/use-cron-tab.js +1 -1
- package/lib/public/js/components/device-pairings.js +12 -12
- package/lib/public/js/components/doctor/findings-list.js +22 -22
- package/lib/public/js/components/doctor/fix-card-modal.js +2 -2
- package/lib/public/js/components/doctor/general-warning.js +5 -5
- package/lib/public/js/components/doctor/index.js +26 -26
- package/lib/public/js/components/doctor/summary-cards.js +5 -5
- package/lib/public/js/components/envars.js +16 -16
- package/lib/public/js/components/features.js +4 -4
- package/lib/public/js/components/file-tree.js +4 -4
- package/lib/public/js/components/file-viewer/diff-viewer.js +2 -2
- package/lib/public/js/components/file-viewer/editor-surface.js +2 -2
- package/lib/public/js/components/file-viewer/frontmatter-panel.js +2 -2
- package/lib/public/js/components/file-viewer/index.js +3 -3
- package/lib/public/js/components/file-viewer/markdown-split-view.js +2 -2
- package/lib/public/js/components/file-viewer/media-preview.js +2 -2
- package/lib/public/js/components/file-viewer/scroll-sync.js +1 -1
- package/lib/public/js/components/file-viewer/sqlite-viewer.js +2 -2
- package/lib/public/js/components/file-viewer/status-banners.js +2 -2
- package/lib/public/js/components/file-viewer/toolbar.js +2 -2
- package/lib/public/js/components/file-viewer/use-editor-line-number-sync.js +1 -1
- package/lib/public/js/components/file-viewer/use-editor-selection-restore.js +1 -1
- package/lib/public/js/components/file-viewer/use-file-diff.js +1 -1
- package/lib/public/js/components/file-viewer/use-file-loader.js +1 -1
- package/lib/public/js/components/file-viewer/use-file-viewer-draft-sync.js +1 -1
- package/lib/public/js/components/file-viewer/use-file-viewer-hotkeys.js +1 -1
- package/lib/public/js/components/file-viewer/use-file-viewer.js +2 -2
- package/lib/public/js/components/gateway.js +12 -12
- package/lib/public/js/components/general/index.js +7 -7
- package/lib/public/js/components/general/use-general-tab.js +1 -1
- package/lib/public/js/components/global-restart-banner.js +2 -2
- package/lib/public/js/components/google/account-row.js +7 -7
- package/lib/public/js/components/google/add-account-modal.js +8 -8
- package/lib/public/js/components/google/gmail-setup-wizard.js +24 -24
- package/lib/public/js/components/google/gmail-watch-toggle.js +5 -5
- package/lib/public/js/components/google/index.js +6 -6
- package/lib/public/js/components/google/use-gmail-watch.js +1 -1
- package/lib/public/js/components/google/use-google-accounts.js +1 -1
- package/lib/public/js/components/icons.js +2 -2
- package/lib/public/js/components/info-tooltip.js +3 -3
- package/lib/public/js/components/loading-spinner.js +2 -2
- package/lib/public/js/components/modal-shell.js +5 -5
- package/lib/public/js/components/models-tab/index.js +11 -11
- package/lib/public/js/components/models-tab/model-picker.js +9 -9
- package/lib/public/js/components/models-tab/provider-auth-card.js +12 -12
- package/lib/public/js/components/models-tab/use-models.js +1 -1
- package/lib/public/js/components/models.js +18 -18
- package/lib/public/js/components/nodes-tab/browser-attach/index.js +15 -25
- package/lib/public/js/components/nodes-tab/connected-nodes/index.js +32 -32
- package/lib/public/js/components/nodes-tab/connected-nodes/use-connected-nodes-card.js +57 -6
- package/lib/public/js/components/nodes-tab/exec-allowlist/index.js +10 -10
- package/lib/public/js/components/nodes-tab/exec-allowlist/use-exec-allowlist.js +1 -1
- package/lib/public/js/components/nodes-tab/exec-config/index.js +13 -13
- package/lib/public/js/components/nodes-tab/exec-config/use-exec-config.js +1 -1
- package/lib/public/js/components/nodes-tab/index.js +2 -2
- package/lib/public/js/components/nodes-tab/setup-wizard/index.js +14 -14
- package/lib/public/js/components/nodes-tab/setup-wizard/use-setup-wizard.js +1 -1
- package/lib/public/js/components/nodes-tab/use-nodes-tab.js +1 -1
- package/lib/public/js/components/onboarding/use-welcome-codex.js +1 -1
- package/lib/public/js/components/onboarding/use-welcome-pairing.js +1 -1
- package/lib/public/js/components/onboarding/use-welcome-storage.js +1 -1
- package/lib/public/js/components/onboarding/welcome-config.js +3 -3
- package/lib/public/js/components/onboarding/welcome-form-step.js +34 -34
- package/lib/public/js/components/onboarding/welcome-header.js +2 -2
- package/lib/public/js/components/onboarding/welcome-import-step.js +22 -22
- package/lib/public/js/components/onboarding/welcome-pairing-step.js +15 -15
- package/lib/public/js/components/onboarding/welcome-placeholder-review-step.js +7 -7
- package/lib/public/js/components/onboarding/welcome-pre-step.js +9 -9
- package/lib/public/js/components/onboarding/welcome-secret-review-step.js +15 -15
- package/lib/public/js/components/onboarding/welcome-setup-step.js +8 -8
- package/lib/public/js/components/overflow-menu.js +3 -3
- package/lib/public/js/components/page-header.js +2 -2
- package/lib/public/js/components/pairings.js +14 -14
- package/lib/public/js/components/pane-shell.js +2 -2
- package/lib/public/js/components/pill-tabs.js +4 -4
- package/lib/public/js/components/pop-actions.js +3 -3
- package/lib/public/js/components/providers.js +17 -17
- package/lib/public/js/components/routes/agents-route.js +2 -2
- package/lib/public/js/components/routes/browse-route.js +2 -2
- package/lib/public/js/components/routes/cron-route.js +2 -2
- package/lib/public/js/components/routes/doctor-route.js +2 -2
- package/lib/public/js/components/routes/envars-route.js +2 -2
- package/lib/public/js/components/routes/general-route.js +2 -2
- package/lib/public/js/components/routes/models-route.js +2 -2
- package/lib/public/js/components/routes/nodes-route.js +2 -2
- package/lib/public/js/components/routes/providers-route.js +2 -2
- package/lib/public/js/components/routes/route-redirect.js +2 -2
- package/lib/public/js/components/routes/telegram-route.js +2 -2
- package/lib/public/js/components/routes/usage-route.js +2 -2
- package/lib/public/js/components/routes/watchdog-route.js +2 -2
- package/lib/public/js/components/routes/webhooks-route.js +2 -2
- package/lib/public/js/components/scope-picker.js +9 -9
- package/lib/public/js/components/secret-input.js +5 -5
- package/lib/public/js/components/segmented-control.js +2 -2
- package/lib/public/js/components/session-select-field.js +7 -7
- package/lib/public/js/components/sidebar-git-panel.js +3 -3
- package/lib/public/js/components/sidebar.js +3 -3
- package/lib/public/js/components/summary-stat-card.js +3 -3
- package/lib/public/js/components/telegram-workspace/index.js +10 -10
- package/lib/public/js/components/telegram-workspace/manage.js +36 -36
- package/lib/public/js/components/telegram-workspace/onboarding.js +73 -73
- package/lib/public/js/components/toast.js +8 -8
- package/lib/public/js/components/toggle-switch.js +2 -2
- package/lib/public/js/components/tooltip.js +5 -5
- package/lib/public/js/components/update-action-button.js +2 -2
- package/lib/public/js/components/update-modal.js +9 -9
- package/lib/public/js/components/usage-tab/constants.js +2 -2
- package/lib/public/js/components/usage-tab/index.js +3 -3
- package/lib/public/js/components/usage-tab/overview-section.js +15 -15
- package/lib/public/js/components/usage-tab/sessions-section.js +19 -19
- package/lib/public/js/components/usage-tab/use-usage-tab.js +2 -2
- package/lib/public/js/components/watchdog-tab/console/index.js +22 -8
- package/lib/public/js/components/watchdog-tab/console/use-console.js +28 -2
- package/lib/public/js/components/watchdog-tab/helpers.js +35 -6
- package/lib/public/js/components/watchdog-tab/incidents/index.js +6 -6
- package/lib/public/js/components/watchdog-tab/incidents/use-incidents.js +1 -1
- package/lib/public/js/components/watchdog-tab/index.js +4 -2
- package/lib/public/js/components/watchdog-tab/resource-bar.js +5 -5
- package/lib/public/js/components/watchdog-tab/resources/index.js +14 -3
- package/lib/public/js/components/watchdog-tab/resources/use-resources.js +1 -1
- package/lib/public/js/components/watchdog-tab/settings/index.js +97 -30
- package/lib/public/js/components/watchdog-tab/settings/use-settings.js +1 -1
- package/lib/public/js/components/watchdog-tab/terminal/index.js +3 -3
- package/lib/public/js/components/watchdog-tab/terminal/use-terminal.js +41 -5
- package/lib/public/js/components/watchdog-tab/use-watchdog-tab.js +2 -0
- package/lib/public/js/components/webhooks/create-webhook-modal/index.js +17 -17
- package/lib/public/js/components/webhooks/helpers.js +3 -3
- package/lib/public/js/components/webhooks/index.js +4 -4
- package/lib/public/js/components/webhooks/request-history/index.js +14 -14
- package/lib/public/js/components/webhooks/request-history/use-request-history.js +1 -1
- package/lib/public/js/components/webhooks/webhook-detail/index.js +41 -41
- package/lib/public/js/components/webhooks/webhook-detail/use-webhook-detail.js +1 -1
- package/lib/public/js/components/webhooks/webhook-list/index.js +11 -11
- package/lib/public/js/components/webhooks/webhook-list/use-webhook-list.js +1 -1
- package/lib/public/js/components/welcome/index.js +3 -3
- package/lib/public/js/components/welcome/use-welcome.js +10 -10
- package/lib/public/js/hooks/use-app-shell-controller.js +22 -4
- package/lib/public/js/hooks/use-app-shell-ui.js +1 -1
- package/lib/public/js/hooks/use-browse-navigation.js +1 -1
- package/lib/public/js/hooks/use-cached-fetch.js +1 -1
- package/lib/public/js/hooks/use-destination-session-selection.js +1 -1
- package/lib/public/js/hooks/use-hash-location.js +1 -1
- package/lib/public/js/hooks/useAgentSessions.js +1 -1
- package/lib/public/js/hooks/usePolling.js +1 -1
- package/lib/public/js/tailwind-config.js +39 -0
- package/lib/public/login.html +3 -18
- package/lib/public/setup.html +2 -18
- package/lib/server/init/register-server-routes.js +2 -0
- package/lib/server/onboarding/github.js +39 -0
- package/lib/server/routes/nodes.js +12 -4
- package/lib/server/routes/pairings.js +5 -1
- package/lib/server/routes/system.js +5 -0
- package/lib/server/routes/watchdog.js +15 -0
- package/lib/server/watchdog.js +137 -51
- package/lib/server.js +2 -0
- package/package.json +14 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { h } from "
|
|
2
|
-
import htm from "
|
|
1
|
+
import { h } from "preact";
|
|
2
|
+
import htm from "htm";
|
|
3
3
|
import {
|
|
4
4
|
formatDurationCompactMs,
|
|
5
5
|
formatInteger,
|
|
@@ -51,14 +51,14 @@ const SessionInlineDetail = ({
|
|
|
51
51
|
if (loadingDetail) {
|
|
52
52
|
return html`
|
|
53
53
|
<div class="ac-history-body">
|
|
54
|
-
<p class="text-xs text-
|
|
54
|
+
<p class="text-xs text-fg-muted">Loading session detail...</p>
|
|
55
55
|
</div>
|
|
56
56
|
`;
|
|
57
57
|
}
|
|
58
58
|
if (!detail) {
|
|
59
59
|
return html`
|
|
60
60
|
<div class="ac-history-body">
|
|
61
|
-
<p class="text-xs text-
|
|
61
|
+
<p class="text-xs text-fg-muted">Session detail not available.</p>
|
|
62
62
|
</div>
|
|
63
63
|
`;
|
|
64
64
|
}
|
|
@@ -68,20 +68,20 @@ const SessionInlineDetail = ({
|
|
|
68
68
|
return html`
|
|
69
69
|
<div class="ac-history-body space-y-3 border-0 pt-0 mt-0">
|
|
70
70
|
<div>
|
|
71
|
-
<p class="text-[11px] text-
|
|
72
|
-
<p class="text-xs text-
|
|
71
|
+
<p class="text-[11px] text-fg-muted mb-1">Session key</p>
|
|
72
|
+
<p class="text-xs text-body font-mono break-all">${sessionKeyValue || "n/a"}</p>
|
|
73
73
|
</div>
|
|
74
74
|
<div class="mt-1.5">
|
|
75
|
-
<p class="text-[11px] text-
|
|
75
|
+
<p class="text-[11px] text-fg-muted mb-1">Model breakdown</p>
|
|
76
76
|
${(detail.modelBreakdown || []).length === 0
|
|
77
|
-
? html`<p class="text-xs text-
|
|
77
|
+
? html`<p class="text-xs text-fg-muted">No model usage recorded.</p>`
|
|
78
78
|
: html`
|
|
79
79
|
<div class="space-y-1.5">
|
|
80
80
|
${(detail.modelBreakdown || []).map(
|
|
81
81
|
(row) => html`
|
|
82
|
-
<div class="flex items-center justify-between gap-3 text-xs px-1 py-0.5 rounded hover:bg-
|
|
83
|
-
<span class="text-
|
|
84
|
-
<span class="inline-flex items-center gap-3 text-
|
|
82
|
+
<div class="flex items-center justify-between gap-3 text-xs px-1 py-0.5 rounded hover:bg-surface transition-colors">
|
|
83
|
+
<span class="text-body truncate">${row.model || "unknown"}</span>
|
|
84
|
+
<span class="inline-flex items-center gap-3 text-fg-muted shrink-0">
|
|
85
85
|
<span>${formatInteger(row.totalTokens)} tok</span>
|
|
86
86
|
<span>${formatUsd(row.totalCost)}</span>
|
|
87
87
|
<span>${formatCountLabel(row.turnCount, "turn", "turns")}</span>
|
|
@@ -93,16 +93,16 @@ const SessionInlineDetail = ({
|
|
|
93
93
|
`}
|
|
94
94
|
</div>
|
|
95
95
|
<div>
|
|
96
|
-
<p class="text-[11px] text-
|
|
96
|
+
<p class="text-[11px] text-fg-muted mb-1">Tool usage</p>
|
|
97
97
|
${(detail.toolUsage || []).length === 0
|
|
98
|
-
? html`<p class="text-xs text-
|
|
98
|
+
? html`<p class="text-xs text-fg-muted">No tool calls recorded.</p>`
|
|
99
99
|
: html`
|
|
100
100
|
<div class="space-y-1.5">
|
|
101
101
|
${(detail.toolUsage || []).map(
|
|
102
102
|
(row) => html`
|
|
103
|
-
<div class="flex items-center justify-between gap-3 text-xs px-1 py-0.5 rounded hover:bg-
|
|
104
|
-
<span class="text-
|
|
105
|
-
<span class="inline-flex items-center gap-3 text-
|
|
103
|
+
<div class="flex items-center justify-between gap-3 text-xs px-1 py-0.5 rounded hover:bg-surface transition-colors">
|
|
104
|
+
<span class="text-body truncate">${row.toolName}</span>
|
|
105
|
+
<span class="inline-flex items-center gap-3 text-fg-muted shrink-0">
|
|
106
106
|
<span>${formatCountLabel(row.callCount, "call", "calls")}</span>
|
|
107
107
|
<span>${(Number(row.errorRate || 0) * 100).toFixed(1)}% err</span>
|
|
108
108
|
<span>${formatDurationCompactMs(row.avgDurationMs)}</span>
|
|
@@ -129,7 +129,7 @@ export const SessionsSection = ({
|
|
|
129
129
|
<h2 class="card-label text-xs mb-3">Sessions</h2>
|
|
130
130
|
<div class="ac-history-list">
|
|
131
131
|
${sessions.length === 0
|
|
132
|
-
? html`<p class="text-xs text-
|
|
132
|
+
? html`<p class="text-xs text-fg-muted">
|
|
133
133
|
${loadingSessions ? "Loading sessions..." : "No sessions recorded yet."}
|
|
134
134
|
</p>`
|
|
135
135
|
: sessions.map(
|
|
@@ -143,13 +143,13 @@ export const SessionsSection = ({
|
|
|
143
143
|
onToggleSession(itemSessionId, isOpen);
|
|
144
144
|
}}
|
|
145
145
|
>
|
|
146
|
-
<summary class="ac-history-summary hover:bg-
|
|
146
|
+
<summary class="ac-history-summary hover:bg-surface transition-colors">
|
|
147
147
|
<div class="ac-history-summary-row">
|
|
148
148
|
<span class="inline-flex items-center gap-2 min-w-0">
|
|
149
149
|
<span class="ac-history-toggle shrink-0" aria-hidden="true">▸</span>
|
|
150
150
|
<${SessionBadges} session=${item} />
|
|
151
151
|
</span>
|
|
152
|
-
<span class="inline-flex items-center gap-3 shrink-0 text-xs text-
|
|
152
|
+
<span class="inline-flex items-center gap-3 shrink-0 text-xs text-fg-muted">
|
|
153
153
|
<span>${formatInteger(item.totalTokens)} tok</span>
|
|
154
154
|
<span>${formatUsd(item.totalCost)}</span>
|
|
155
155
|
<span>
|
|
@@ -4,7 +4,8 @@ import {
|
|
|
4
4
|
useMemo,
|
|
5
5
|
useRef,
|
|
6
6
|
useState,
|
|
7
|
-
} from "
|
|
7
|
+
} from "preact/hooks";
|
|
8
|
+
import Chart from "chart.js/auto";
|
|
8
9
|
import {
|
|
9
10
|
fetchUsageSessionDetail,
|
|
10
11
|
fetchUsageSessions,
|
|
@@ -233,7 +234,6 @@ export const useUsageTab = ({ sessionId = "" }) => {
|
|
|
233
234
|
|
|
234
235
|
useEffect(() => {
|
|
235
236
|
const canvas = overviewCanvasRef.current;
|
|
236
|
-
const Chart = window.Chart;
|
|
237
237
|
if (!canvas || !Chart) return;
|
|
238
238
|
if (overviewChartRef.current) {
|
|
239
239
|
overviewChartRef.current.destroy();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { h } from "
|
|
2
|
-
import htm from "
|
|
1
|
+
import { h } from "preact";
|
|
2
|
+
import htm from "htm";
|
|
3
|
+
import { FileCopyLineIcon } from "../../icons.js";
|
|
3
4
|
import {
|
|
4
5
|
kWatchdogConsoleTabLogs,
|
|
5
6
|
kWatchdogConsoleTabTerminal,
|
|
@@ -22,26 +23,28 @@ export const WatchdogConsoleCard = ({
|
|
|
22
23
|
logsRef = null,
|
|
23
24
|
logs = "",
|
|
24
25
|
loadingLogs = true,
|
|
26
|
+
copyingAll = false,
|
|
25
27
|
terminalPanelRef = null,
|
|
26
28
|
terminalHostRef = null,
|
|
27
29
|
terminalInstanceRef = null,
|
|
28
30
|
logsPanelHeightPx = 320,
|
|
31
|
+
onCopyAll = () => {},
|
|
29
32
|
}) => html`
|
|
30
33
|
<div class="bg-surface border border-border rounded-xl p-4">
|
|
31
34
|
<div class="flex items-center justify-between gap-2 mb-3">
|
|
32
35
|
<div
|
|
33
|
-
class="inline-flex items-center rounded-lg border border-border bg-
|
|
36
|
+
class="inline-flex items-center rounded-lg border border-border bg-field p-0.5"
|
|
34
37
|
>
|
|
35
38
|
<button
|
|
36
39
|
type="button"
|
|
37
|
-
class=${`px-2.5 py-1 text-xs rounded-md ${activeConsoleTab === kWatchdogConsoleTabLogs ? "bg-surface text-
|
|
40
|
+
class=${`px-2.5 py-1 text-xs rounded-md ${activeConsoleTab === kWatchdogConsoleTabLogs ? "bg-surface text-bright" : "text-fg-muted hover:text-body"}`}
|
|
38
41
|
onClick=${() => onSelectConsoleTab(kWatchdogConsoleTabLogs)}
|
|
39
42
|
>
|
|
40
43
|
Logs
|
|
41
44
|
</button>
|
|
42
45
|
<button
|
|
43
46
|
type="button"
|
|
44
|
-
class=${`px-2.5 py-1 text-xs rounded-md ${activeConsoleTab === kWatchdogConsoleTabTerminal ? "bg-surface text-
|
|
47
|
+
class=${`px-2.5 py-1 text-xs rounded-md ${activeConsoleTab === kWatchdogConsoleTabTerminal ? "bg-surface text-bright" : "text-fg-muted hover:text-body"}`}
|
|
45
48
|
onClick=${() => onSelectConsoleTab(kWatchdogConsoleTabTerminal)}
|
|
46
49
|
>
|
|
47
50
|
Terminal
|
|
@@ -50,7 +53,7 @@ export const WatchdogConsoleCard = ({
|
|
|
50
53
|
<div class="flex items-center gap-2">
|
|
51
54
|
${activeConsoleTab === kWatchdogConsoleTabLogs
|
|
52
55
|
? html`
|
|
53
|
-
<label class="inline-flex items-center gap-2 text-xs text-
|
|
56
|
+
<label class="inline-flex items-center gap-2 text-xs text-fg-muted">
|
|
54
57
|
<input
|
|
55
58
|
type="checkbox"
|
|
56
59
|
checked=${stickToBottom}
|
|
@@ -65,7 +68,7 @@ export const WatchdogConsoleCard = ({
|
|
|
65
68
|
${terminalUiSettling
|
|
66
69
|
? null
|
|
67
70
|
: html`
|
|
68
|
-
<span class="text-xs text-
|
|
71
|
+
<span class="text-xs text-fg-muted">
|
|
69
72
|
${connectingTerminal
|
|
70
73
|
? "Connecting..."
|
|
71
74
|
: terminalEnded
|
|
@@ -93,11 +96,22 @@ export const WatchdogConsoleCard = ({
|
|
|
93
96
|
<div class=${activeConsoleTab === kWatchdogConsoleTabLogs ? "" : "hidden"}>
|
|
94
97
|
<pre
|
|
95
98
|
ref=${logsRef}
|
|
96
|
-
class="watchdog-logs-panel bg-
|
|
99
|
+
class="watchdog-logs-panel bg-field border border-border rounded-lg p-3 overflow-auto text-xs text-body whitespace-pre-wrap break-words"
|
|
97
100
|
style=${{ height: `${logsPanelHeightPx}px` }}
|
|
98
101
|
>
|
|
99
102
|
${loadingLogs ? "Loading logs..." : logs || "No logs yet."}</pre
|
|
100
103
|
>
|
|
104
|
+
<div class="mt-3 flex justify-end">
|
|
105
|
+
<button
|
|
106
|
+
type="button"
|
|
107
|
+
class=${`ac-btn-secondary text-xs px-2.5 py-1 rounded-lg inline-flex items-center gap-1.5 ${copyingAll ? "opacity-50 cursor-not-allowed" : ""}`}
|
|
108
|
+
onClick=${onCopyAll}
|
|
109
|
+
disabled=${copyingAll}
|
|
110
|
+
>
|
|
111
|
+
<${FileCopyLineIcon} className="w-3.5 h-3.5" />
|
|
112
|
+
${copyingAll ? "Copying..." : "Copy all"}
|
|
113
|
+
</button>
|
|
114
|
+
</div>
|
|
101
115
|
</div>
|
|
102
116
|
<div
|
|
103
117
|
class=${activeConsoleTab === kWatchdogConsoleTabTerminal
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from "
|
|
1
|
+
import { useEffect, useRef, useState } from "preact/hooks";
|
|
2
2
|
import { fetchWatchdogLogs } from "../../../lib/api.js";
|
|
3
|
+
import { copyTextToClipboard } from "../../../lib/clipboard.js";
|
|
3
4
|
import { readUiSettings, writeUiSettings } from "../../../lib/ui-settings.js";
|
|
5
|
+
import { showToast } from "../../toast.js";
|
|
4
6
|
import {
|
|
5
7
|
clampWatchdogLogsPanelHeight,
|
|
8
|
+
formatWatchdogCopyAllText,
|
|
6
9
|
kWatchdogConsoleTabLogs,
|
|
7
10
|
kWatchdogConsoleTabTerminal,
|
|
8
11
|
kWatchdogConsoleTabUiSettingKey,
|
|
@@ -12,9 +15,11 @@ import {
|
|
|
12
15
|
} from "../helpers.js";
|
|
13
16
|
import { useWatchdogTerminal } from "../terminal/use-terminal.js";
|
|
14
17
|
|
|
15
|
-
export const useWatchdogConsole = (
|
|
18
|
+
export const useWatchdogConsole = ({
|
|
19
|
+
} = {}) => {
|
|
16
20
|
const [logs, setLogs] = useState("");
|
|
17
21
|
const [loadingLogs, setLoadingLogs] = useState(true);
|
|
22
|
+
const [copyingAll, setCopyingAll] = useState(false);
|
|
18
23
|
const [stickToBottom, setStickToBottom] = useState(true);
|
|
19
24
|
const [activeConsoleTab, setActiveConsoleTab] = useState(() => {
|
|
20
25
|
const settings = readUiSettings();
|
|
@@ -120,9 +125,29 @@ export const useWatchdogConsole = () => {
|
|
|
120
125
|
setActiveConsoleTab(kWatchdogConsoleTabTerminal);
|
|
121
126
|
};
|
|
122
127
|
|
|
128
|
+
const handleCopyAll = async () => {
|
|
129
|
+
if (copyingAll) return;
|
|
130
|
+
setCopyingAll(true);
|
|
131
|
+
try {
|
|
132
|
+
const text = formatWatchdogCopyAllText({
|
|
133
|
+
logs,
|
|
134
|
+
});
|
|
135
|
+
const copied = await copyTextToClipboard(text);
|
|
136
|
+
if (!copied) {
|
|
137
|
+
throw new Error("Could not copy watchdog export");
|
|
138
|
+
}
|
|
139
|
+
showToast("Copied watchdog logs", "success");
|
|
140
|
+
} catch (error) {
|
|
141
|
+
showToast(error.message || "Could not copy watchdog export", "error");
|
|
142
|
+
} finally {
|
|
143
|
+
setCopyingAll(false);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
123
147
|
return {
|
|
124
148
|
logs,
|
|
125
149
|
loadingLogs,
|
|
150
|
+
copyingAll,
|
|
126
151
|
stickToBottom,
|
|
127
152
|
setStickToBottom,
|
|
128
153
|
activeConsoleTab,
|
|
@@ -132,6 +157,7 @@ export const useWatchdogConsole = () => {
|
|
|
132
157
|
terminalPanelRef,
|
|
133
158
|
terminalHostRef,
|
|
134
159
|
onRestartTerminalSession,
|
|
160
|
+
onCopyAll: handleCopyAll,
|
|
135
161
|
...terminal,
|
|
136
162
|
};
|
|
137
163
|
};
|
|
@@ -4,18 +4,28 @@ export const kWatchdogConsoleTabUiSettingKey = "watchdogConsoleTab";
|
|
|
4
4
|
export const kWatchdogLogsPanelHeightUiSettingKey = "watchdogLogsPanelHeightPx";
|
|
5
5
|
export const kWatchdogLogsPanelDefaultHeightPx = 320;
|
|
6
6
|
export const kWatchdogLogsPanelMinHeightPx = 160;
|
|
7
|
-
export const kXtermCssUrl =
|
|
8
|
-
"https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/css/xterm.css";
|
|
7
|
+
export const kXtermCssUrl = "/css/vendor/xterm.css";
|
|
9
8
|
export const kWatchdogTerminalWsPath = "/api/watchdog/terminal/ws";
|
|
10
9
|
|
|
11
10
|
let xtermModulesPromise = null;
|
|
12
11
|
|
|
13
12
|
export const loadXtermModules = () => {
|
|
14
13
|
if (!xtermModulesPromise) {
|
|
15
|
-
xtermModulesPromise = Promise.all([
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
xtermModulesPromise = Promise.all([import("@xterm/xterm"), import("@xterm/addon-fit")]).then(
|
|
15
|
+
([xtermModule, fitAddonModule]) => {
|
|
16
|
+
const Terminal =
|
|
17
|
+
xtermModule?.Terminal || xtermModule?.default?.Terminal || null;
|
|
18
|
+
const FitAddon =
|
|
19
|
+
fitAddonModule?.FitAddon || fitAddonModule?.default?.FitAddon || null;
|
|
20
|
+
if (typeof Terminal !== "function") {
|
|
21
|
+
throw new Error("Xterm Terminal export not found");
|
|
22
|
+
}
|
|
23
|
+
if (typeof FitAddon !== "function") {
|
|
24
|
+
throw new Error("Xterm FitAddon export not found");
|
|
25
|
+
}
|
|
26
|
+
return { Terminal, FitAddon };
|
|
27
|
+
},
|
|
28
|
+
);
|
|
19
29
|
}
|
|
20
30
|
return xtermModulesPromise;
|
|
21
31
|
};
|
|
@@ -104,3 +114,22 @@ export const getIncidentStatusTone = (event) => {
|
|
|
104
114
|
label: "Unknown",
|
|
105
115
|
};
|
|
106
116
|
};
|
|
117
|
+
|
|
118
|
+
export const formatWatchdogCopyAllText = ({
|
|
119
|
+
logs = "",
|
|
120
|
+
generatedAt = null,
|
|
121
|
+
} = {}) => {
|
|
122
|
+
const sections = [];
|
|
123
|
+
const generatedAtLabel =
|
|
124
|
+
generatedAt instanceof Date && !Number.isNaN(generatedAt.getTime())
|
|
125
|
+
? generatedAt.toISOString()
|
|
126
|
+
: new Date().toISOString();
|
|
127
|
+
|
|
128
|
+
sections.push(`# AlphaClaw Watchdog Export`);
|
|
129
|
+
sections.push(`Generated at: ${generatedAtLabel}`);
|
|
130
|
+
|
|
131
|
+
sections.push(`## Gateway Logs`);
|
|
132
|
+
sections.push(String(logs || "").trim() || "No logs yet.");
|
|
133
|
+
|
|
134
|
+
return sections.join("\n\n").trim();
|
|
135
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { h } from "
|
|
2
|
-
import htm from "
|
|
1
|
+
import { h } from "preact";
|
|
2
|
+
import htm from "htm";
|
|
3
3
|
import { getIncidentStatusTone } from "../helpers.js";
|
|
4
4
|
|
|
5
5
|
const html = htm.bind(h);
|
|
@@ -11,13 +11,13 @@ export const WatchdogIncidentsCard = ({
|
|
|
11
11
|
<div class="bg-surface border border-border rounded-xl p-4">
|
|
12
12
|
<div class="flex items-center justify-between gap-2 mb-3">
|
|
13
13
|
<h2 class="card-label">Recent incidents</h2>
|
|
14
|
-
<button class="text-xs text-
|
|
14
|
+
<button class="text-xs text-fg-muted hover:text-body" onclick=${onRefresh}>
|
|
15
15
|
Refresh
|
|
16
16
|
</button>
|
|
17
17
|
</div>
|
|
18
18
|
<div class="ac-history-list">
|
|
19
19
|
${events.length === 0 &&
|
|
20
|
-
html`<p class="text-xs text-
|
|
20
|
+
html`<p class="text-xs text-fg-muted">No incidents recorded.</p>`}
|
|
21
21
|
${events.map((event) => {
|
|
22
22
|
const tone = getIncidentStatusTone(event);
|
|
23
23
|
return html`
|
|
@@ -40,9 +40,9 @@ export const WatchdogIncidentsCard = ({
|
|
|
40
40
|
></span>
|
|
41
41
|
</div>
|
|
42
42
|
</summary>
|
|
43
|
-
<div class="ac-history-body text-xs text-
|
|
43
|
+
<div class="ac-history-body text-xs text-fg-muted">
|
|
44
44
|
<div>Source: ${event.source || "unknown"}</div>
|
|
45
|
-
<pre class="mt-2 bg-
|
|
45
|
+
<pre class="mt-2 bg-field rounded p-2 whitespace-pre-wrap break-words">
|
|
46
46
|
${typeof event.details === "string"
|
|
47
47
|
? event.details
|
|
48
48
|
: JSON.stringify(event.details || {}, null, 2)}</pre
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { h } from "
|
|
2
|
-
import htm from "
|
|
1
|
+
import { h } from "preact";
|
|
2
|
+
import htm from "htm";
|
|
3
3
|
import { Gateway } from "../gateway.js";
|
|
4
4
|
import { useWatchdogTab } from "./use-watchdog-tab.js";
|
|
5
5
|
import { WatchdogResourcesCard } from "./resources/index.js";
|
|
@@ -69,10 +69,12 @@ export const WatchdogTab = ({
|
|
|
69
69
|
logsRef=${state.logsRef}
|
|
70
70
|
logs=${state.logs}
|
|
71
71
|
loadingLogs=${state.loadingLogs}
|
|
72
|
+
copyingAll=${state.copyingAll}
|
|
72
73
|
terminalPanelRef=${state.terminalPanelRef}
|
|
73
74
|
terminalHostRef=${state.terminalHostRef}
|
|
74
75
|
terminalInstanceRef=${state.terminalInstanceRef}
|
|
75
76
|
logsPanelHeightPx=${state.logsPanelHeightPx}
|
|
77
|
+
onCopyAll=${state.onCopyAll}
|
|
76
78
|
/>
|
|
77
79
|
|
|
78
80
|
<${WatchdogIncidentsCard}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { h } from "
|
|
2
|
-
import htm from "
|
|
1
|
+
import { h } from "preact";
|
|
2
|
+
import htm from "htm";
|
|
3
3
|
|
|
4
4
|
const html = htm.bind(h);
|
|
5
5
|
|
|
@@ -21,7 +21,7 @@ export const ResourceBar = ({
|
|
|
21
21
|
onclick=${onToggle || undefined}
|
|
22
22
|
>
|
|
23
23
|
<span
|
|
24
|
-
class=${`text-xs text-
|
|
24
|
+
class=${`text-xs text-fg-muted ${onToggle ? "group-hover:text-body transition-colors" : ""}`}
|
|
25
25
|
>${label}</span
|
|
26
26
|
>
|
|
27
27
|
<div
|
|
@@ -53,7 +53,7 @@ export const ResourceBar = ({
|
|
|
53
53
|
`}
|
|
54
54
|
</div>
|
|
55
55
|
<div class="flex flex-wrap items-center gap-x-3 mt-2.5">
|
|
56
|
-
<span class="text-xs text-
|
|
56
|
+
<span class="text-xs text-fg-muted font-mono flex-1">${detail}</span>
|
|
57
57
|
${expanded &&
|
|
58
58
|
segments &&
|
|
59
59
|
segments
|
|
@@ -61,7 +61,7 @@ export const ResourceBar = ({
|
|
|
61
61
|
.map(
|
|
62
62
|
(segment) => html`
|
|
63
63
|
<span
|
|
64
|
-
class="inline-flex items-center gap-1 text-xs text-
|
|
64
|
+
class="inline-flex items-center gap-1 text-xs text-fg-muted font-mono"
|
|
65
65
|
>
|
|
66
66
|
<span
|
|
67
67
|
class="inline-block w-1.5 h-1.5 rounded-full"
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { h } from "
|
|
2
|
-
import htm from "
|
|
1
|
+
import { h } from "preact";
|
|
2
|
+
import htm from "htm";
|
|
3
3
|
import { formatBytes } from "../helpers.js";
|
|
4
4
|
import { ResourceBar } from "../resource-bar.js";
|
|
5
|
+
import { Tooltip } from "../../tooltip.js";
|
|
5
6
|
|
|
6
7
|
const html = htm.bind(h);
|
|
7
8
|
|
|
@@ -11,6 +12,16 @@ export const WatchdogResourcesCard = ({
|
|
|
11
12
|
onSetMemoryExpanded = () => {},
|
|
12
13
|
}) => {
|
|
13
14
|
if (!resources) return null;
|
|
15
|
+
const diskLabel = resources.disk?.path
|
|
16
|
+
? html`
|
|
17
|
+
<${Tooltip}
|
|
18
|
+
text=${resources.disk.path}
|
|
19
|
+
widthClass="w-auto max-w-80 whitespace-normal break-all"
|
|
20
|
+
>
|
|
21
|
+
<span class="inline-block cursor-help">Disk</span>
|
|
22
|
+
</${Tooltip}>
|
|
23
|
+
`
|
|
24
|
+
: "Disk";
|
|
14
25
|
const memorySegments = (() => {
|
|
15
26
|
const processes = resources.processes;
|
|
16
27
|
const totalBytes = resources.memory?.totalBytes;
|
|
@@ -67,7 +78,7 @@ export const WatchdogResourcesCard = ({
|
|
|
67
78
|
onToggle=${() => onSetMemoryExpanded(true)}
|
|
68
79
|
/>
|
|
69
80
|
<${ResourceBar}
|
|
70
|
-
label=${
|
|
81
|
+
label=${diskLabel}
|
|
71
82
|
percent=${resources.disk?.percent}
|
|
72
83
|
detail=${`${formatBytes(resources.disk?.usedBytes)} / ${formatBytes(resources.disk?.totalBytes)}`}
|
|
73
84
|
/>
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { h } from "
|
|
2
|
-
import
|
|
1
|
+
import { h } from "preact";
|
|
2
|
+
import { useState } from "preact/hooks";
|
|
3
|
+
import htm from "htm";
|
|
3
4
|
import { InfoTooltip } from "../../info-tooltip.js";
|
|
4
5
|
import { ToggleSwitch } from "../../toggle-switch.js";
|
|
6
|
+
import { showToast } from "../../toast.js";
|
|
5
7
|
|
|
6
8
|
const html = htm.bind(h);
|
|
7
9
|
|
|
@@ -10,35 +12,100 @@ export const WatchdogSettingsCard = ({
|
|
|
10
12
|
savingSettings = false,
|
|
11
13
|
onToggleAutoRepair = () => {},
|
|
12
14
|
onToggleNotifications = () => {},
|
|
13
|
-
}) =>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
}) => {
|
|
16
|
+
const [testing, setTesting] = useState(false);
|
|
17
|
+
const [testResult, setTestResult] = useState(null);
|
|
18
|
+
|
|
19
|
+
const handleTestNotification = async () => {
|
|
20
|
+
setTesting(true);
|
|
21
|
+
setTestResult(null);
|
|
22
|
+
try {
|
|
23
|
+
const res = await fetch("/api/watchdog/test-notification", { method: "POST" });
|
|
24
|
+
const data = await res.json();
|
|
25
|
+
if (!data?.ok) {
|
|
26
|
+
setTestResult(data);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const channels = data.result?.channels || data.result || {};
|
|
31
|
+
const parts = [];
|
|
32
|
+
for (const channel of ["telegram", "discord", "slack"]) {
|
|
33
|
+
const ch = channels[channel];
|
|
34
|
+
if (!ch || ch.skipped) continue;
|
|
35
|
+
if (ch.sent > 0) parts.push(`${channel}: ${ch.sent} sent`);
|
|
36
|
+
if (ch.failed > 0) parts.push(`${channel}: ${ch.failed} failed`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (parts.length === 0) {
|
|
40
|
+
showToast("No channels configured", "warning");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const hasFailures = parts.some((part) => part.includes("failed"));
|
|
45
|
+
showToast(
|
|
46
|
+
hasFailures ? parts.join(", ") : `Test notification sent: ${parts.join(", ")}`,
|
|
47
|
+
hasFailures ? "warning" : "success",
|
|
48
|
+
);
|
|
49
|
+
} catch (err) {
|
|
50
|
+
setTestResult({ ok: false, error: err.message });
|
|
51
|
+
} finally {
|
|
52
|
+
setTesting(false);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const formatResult = (result) => {
|
|
57
|
+
if (!result) return null;
|
|
58
|
+
return html`<span class="text-status-error-muted text-xs">
|
|
59
|
+
${result.error || "Failed"}
|
|
60
|
+
</span>`;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return html`
|
|
64
|
+
<div class="bg-surface border border-border rounded-xl p-4">
|
|
65
|
+
<div class="flex items-center justify-between gap-3">
|
|
66
|
+
<div class="inline-flex items-center gap-2 text-xs text-fg-muted">
|
|
67
|
+
<span>Auto-repair</span>
|
|
68
|
+
<${InfoTooltip}
|
|
69
|
+
text="Automatically runs OpenClaw doctor repair when watchdog detects gateway health failures or crash loops."
|
|
70
|
+
/>
|
|
71
|
+
</div>
|
|
72
|
+
<${ToggleSwitch}
|
|
73
|
+
checked=${!!settings.autoRepair}
|
|
74
|
+
disabled=${savingSettings}
|
|
75
|
+
onChange=${onToggleAutoRepair}
|
|
76
|
+
label=""
|
|
20
77
|
/>
|
|
21
78
|
</div>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
79
|
+
<div class="flex items-center justify-between gap-3 mt-3">
|
|
80
|
+
<div class="inline-flex items-center gap-2 text-xs text-fg-muted">
|
|
81
|
+
<span>Notifications</span>
|
|
82
|
+
<${InfoTooltip}
|
|
83
|
+
text="Sends channel notices for watchdog alerts and auto-repair outcomes."
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
<div class="flex items-center gap-2">
|
|
87
|
+
<button
|
|
88
|
+
class=${`text-xs px-2 py-1 rounded-lg ac-btn-ghost disabled:opacity-50 disabled:cursor-not-allowed ${
|
|
89
|
+
settings.notificationsEnabled ? "" : "invisible pointer-events-none"
|
|
90
|
+
}`}
|
|
91
|
+
onClick=${handleTestNotification}
|
|
92
|
+
disabled=${testing || savingSettings || !settings.notificationsEnabled}
|
|
93
|
+
aria-hidden=${!settings.notificationsEnabled}
|
|
94
|
+
tabIndex=${settings.notificationsEnabled ? 0 : -1}
|
|
95
|
+
>
|
|
96
|
+
${testing ? "Sending..." : "Test"}
|
|
97
|
+
</button>
|
|
98
|
+
<${ToggleSwitch}
|
|
99
|
+
checked=${!!settings.notificationsEnabled}
|
|
100
|
+
disabled=${savingSettings}
|
|
101
|
+
onChange=${onToggleNotifications}
|
|
102
|
+
label=""
|
|
103
|
+
/>
|
|
104
|
+
</div>
|
|
35
105
|
</div>
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
onChange=${onToggleNotifications}
|
|
40
|
-
label=""
|
|
41
|
-
/>
|
|
106
|
+
${testResult
|
|
107
|
+
? html`<div class="mt-2">${formatResult(testResult)}</div>`
|
|
108
|
+
: null}
|
|
42
109
|
</div>
|
|
43
|
-
|
|
44
|
-
|
|
110
|
+
`;
|
|
111
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { h } from "
|
|
2
|
-
import htm from "
|
|
1
|
+
import { h } from "preact";
|
|
2
|
+
import htm from "htm";
|
|
3
3
|
|
|
4
4
|
const html = htm.bind(h);
|
|
5
5
|
|
|
@@ -11,7 +11,7 @@ export const WatchdogTerminal = ({
|
|
|
11
11
|
}) => html`
|
|
12
12
|
<div
|
|
13
13
|
ref=${panelRef}
|
|
14
|
-
class="watchdog-logs-panel bg-
|
|
14
|
+
class="watchdog-logs-panel bg-field border border-border rounded-lg p-3 overflow-hidden"
|
|
15
15
|
style=${{ height: `${panelHeightPx}px` }}
|
|
16
16
|
onClick=${() => terminalInstanceRef?.current?.focus()}
|
|
17
17
|
>
|