@chrysb/alphaclaw 0.8.1 → 0.8.3-beta.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.
Files changed (219) hide show
  1. package/README.md +33 -24
  2. package/bin/alphaclaw.js +13 -2
  3. package/lib/public/css/chat.css +426 -0
  4. package/lib/public/css/explorer.css +101 -0
  5. package/lib/public/css/tailwind.generated.css +1 -0
  6. package/lib/public/css/tailwind.input.css +3 -0
  7. package/lib/public/css/theme.css +28 -0
  8. package/lib/public/css/vendor/xterm.css +218 -0
  9. package/lib/public/dist/app.bundle.js +10706 -0
  10. package/lib/public/dist/chunks/addon-fit-W4YZGRNV.js +1 -0
  11. package/lib/public/dist/chunks/chunk-72ZECFVW.js +1 -0
  12. package/lib/public/dist/chunks/xterm-KOX4YMOF.js +9 -0
  13. package/lib/public/js/app.js +38 -4
  14. package/lib/public/js/components/action-button.js +8 -8
  15. package/lib/public/js/components/add-channel-menu.js +2 -2
  16. package/lib/public/js/components/agent-send-modal.js +6 -6
  17. package/lib/public/js/components/agents-tab/agent-bindings-section/channel-item-trailing.js +7 -7
  18. package/lib/public/js/components/agents-tab/agent-bindings-section/index.js +3 -3
  19. package/lib/public/js/components/agents-tab/agent-bindings-section/use-agent-bindings.js +1 -1
  20. package/lib/public/js/components/agents-tab/agent-bindings-section/use-channel-items.js +4 -4
  21. package/lib/public/js/components/agents-tab/agent-detail-panel.js +5 -5
  22. package/lib/public/js/components/agents-tab/agent-identity-section.js +18 -18
  23. package/lib/public/js/components/agents-tab/agent-overview/index.js +2 -2
  24. package/lib/public/js/components/agents-tab/agent-overview/manage-card.js +2 -2
  25. package/lib/public/js/components/agents-tab/agent-overview/model-card.js +8 -8
  26. package/lib/public/js/components/agents-tab/agent-overview/tools-card.js +5 -5
  27. package/lib/public/js/components/agents-tab/agent-overview/use-model-card.js +1 -1
  28. package/lib/public/js/components/agents-tab/agent-overview/use-workspace-card.js +1 -1
  29. package/lib/public/js/components/agents-tab/agent-overview/workspace-card.js +4 -4
  30. package/lib/public/js/components/agents-tab/agent-pairing-section.js +4 -4
  31. package/lib/public/js/components/agents-tab/agent-tools/index.js +5 -5
  32. package/lib/public/js/components/agents-tab/agent-tools/use-agent-tools.js +1 -1
  33. package/lib/public/js/components/agents-tab/create-agent-modal.js +13 -13
  34. package/lib/public/js/components/agents-tab/create-channel-modal.js +34 -34
  35. package/lib/public/js/components/agents-tab/delete-agent-dialog.js +3 -3
  36. package/lib/public/js/components/agents-tab/edit-agent-modal.js +9 -9
  37. package/lib/public/js/components/agents-tab/index.js +3 -3
  38. package/lib/public/js/components/agents-tab/use-agents.js +1 -1
  39. package/lib/public/js/components/badge.js +6 -6
  40. package/lib/public/js/components/channel-account-status-badge.js +2 -2
  41. package/lib/public/js/components/channel-operations-panel.js +2 -2
  42. package/lib/public/js/components/channels.js +9 -9
  43. package/lib/public/js/components/confirm-dialog.js +5 -5
  44. package/lib/public/js/components/credentials-modal.js +22 -22
  45. package/lib/public/js/components/cron-tab/cron-calendar.js +6 -6
  46. package/lib/public/js/components/cron-tab/cron-insights-panel.js +10 -10
  47. package/lib/public/js/components/cron-tab/cron-job-detail.js +4 -4
  48. package/lib/public/js/components/cron-tab/cron-job-list.js +4 -4
  49. package/lib/public/js/components/cron-tab/cron-job-settings-card.js +15 -15
  50. package/lib/public/js/components/cron-tab/cron-job-trends-panel.js +5 -5
  51. package/lib/public/js/components/cron-tab/cron-job-usage.js +16 -16
  52. package/lib/public/js/components/cron-tab/cron-overview.js +10 -10
  53. package/lib/public/js/components/cron-tab/cron-prompt-editor.js +3 -3
  54. package/lib/public/js/components/cron-tab/cron-run-history-panel.js +39 -39
  55. package/lib/public/js/components/cron-tab/cron-runs-trend-card.js +4 -4
  56. package/lib/public/js/components/cron-tab/index.js +5 -5
  57. package/lib/public/js/components/cron-tab/use-cron-tab.js +1 -1
  58. package/lib/public/js/components/device-pairings.js +12 -12
  59. package/lib/public/js/components/doctor/findings-list.js +22 -22
  60. package/lib/public/js/components/doctor/fix-card-modal.js +2 -2
  61. package/lib/public/js/components/doctor/general-warning.js +5 -5
  62. package/lib/public/js/components/doctor/index.js +26 -26
  63. package/lib/public/js/components/doctor/summary-cards.js +5 -5
  64. package/lib/public/js/components/envars.js +16 -16
  65. package/lib/public/js/components/features.js +4 -4
  66. package/lib/public/js/components/file-tree.js +4 -4
  67. package/lib/public/js/components/file-viewer/diff-viewer.js +2 -2
  68. package/lib/public/js/components/file-viewer/editor-surface.js +2 -2
  69. package/lib/public/js/components/file-viewer/frontmatter-panel.js +2 -2
  70. package/lib/public/js/components/file-viewer/index.js +3 -3
  71. package/lib/public/js/components/file-viewer/markdown-split-view.js +2 -2
  72. package/lib/public/js/components/file-viewer/media-preview.js +2 -2
  73. package/lib/public/js/components/file-viewer/scroll-sync.js +1 -1
  74. package/lib/public/js/components/file-viewer/sqlite-viewer.js +2 -2
  75. package/lib/public/js/components/file-viewer/status-banners.js +2 -2
  76. package/lib/public/js/components/file-viewer/toolbar.js +2 -2
  77. package/lib/public/js/components/file-viewer/use-editor-line-number-sync.js +1 -1
  78. package/lib/public/js/components/file-viewer/use-editor-selection-restore.js +1 -1
  79. package/lib/public/js/components/file-viewer/use-file-diff.js +1 -1
  80. package/lib/public/js/components/file-viewer/use-file-loader.js +1 -1
  81. package/lib/public/js/components/file-viewer/use-file-viewer-draft-sync.js +1 -1
  82. package/lib/public/js/components/file-viewer/use-file-viewer-hotkeys.js +1 -1
  83. package/lib/public/js/components/file-viewer/use-file-viewer.js +2 -2
  84. package/lib/public/js/components/gateway.js +12 -12
  85. package/lib/public/js/components/general/index.js +7 -7
  86. package/lib/public/js/components/general/use-general-tab.js +1 -1
  87. package/lib/public/js/components/global-restart-banner.js +2 -2
  88. package/lib/public/js/components/google/account-row.js +7 -7
  89. package/lib/public/js/components/google/add-account-modal.js +8 -8
  90. package/lib/public/js/components/google/gmail-setup-wizard.js +24 -24
  91. package/lib/public/js/components/google/gmail-watch-toggle.js +5 -5
  92. package/lib/public/js/components/google/index.js +6 -6
  93. package/lib/public/js/components/google/use-gmail-watch.js +1 -1
  94. package/lib/public/js/components/google/use-google-accounts.js +1 -1
  95. package/lib/public/js/components/icons.js +2 -2
  96. package/lib/public/js/components/info-tooltip.js +3 -3
  97. package/lib/public/js/components/loading-spinner.js +2 -2
  98. package/lib/public/js/components/modal-shell.js +5 -5
  99. package/lib/public/js/components/models-tab/index.js +11 -11
  100. package/lib/public/js/components/models-tab/model-picker.js +9 -9
  101. package/lib/public/js/components/models-tab/provider-auth-card.js +12 -12
  102. package/lib/public/js/components/models-tab/use-models.js +1 -1
  103. package/lib/public/js/components/models.js +18 -18
  104. package/lib/public/js/components/nodes-tab/browser-attach/index.js +5 -5
  105. package/lib/public/js/components/nodes-tab/connected-nodes/index.js +34 -32
  106. package/lib/public/js/components/nodes-tab/connected-nodes/use-connected-nodes-card.js +18 -3
  107. package/lib/public/js/components/nodes-tab/exec-allowlist/index.js +10 -10
  108. package/lib/public/js/components/nodes-tab/exec-allowlist/use-exec-allowlist.js +1 -1
  109. package/lib/public/js/components/nodes-tab/exec-config/index.js +13 -13
  110. package/lib/public/js/components/nodes-tab/exec-config/use-exec-config.js +1 -1
  111. package/lib/public/js/components/nodes-tab/index.js +2 -2
  112. package/lib/public/js/components/nodes-tab/setup-wizard/index.js +14 -14
  113. package/lib/public/js/components/nodes-tab/setup-wizard/use-setup-wizard.js +1 -1
  114. package/lib/public/js/components/nodes-tab/use-nodes-tab.js +1 -1
  115. package/lib/public/js/components/onboarding/use-welcome-codex.js +1 -1
  116. package/lib/public/js/components/onboarding/use-welcome-pairing.js +1 -1
  117. package/lib/public/js/components/onboarding/use-welcome-storage.js +1 -1
  118. package/lib/public/js/components/onboarding/welcome-config.js +3 -3
  119. package/lib/public/js/components/onboarding/welcome-form-step.js +34 -34
  120. package/lib/public/js/components/onboarding/welcome-header.js +2 -2
  121. package/lib/public/js/components/onboarding/welcome-import-step.js +22 -22
  122. package/lib/public/js/components/onboarding/welcome-pairing-step.js +15 -15
  123. package/lib/public/js/components/onboarding/welcome-placeholder-review-step.js +7 -7
  124. package/lib/public/js/components/onboarding/welcome-pre-step.js +9 -9
  125. package/lib/public/js/components/onboarding/welcome-secret-review-step.js +15 -15
  126. package/lib/public/js/components/onboarding/welcome-setup-step.js +8 -8
  127. package/lib/public/js/components/overflow-menu.js +3 -3
  128. package/lib/public/js/components/page-header.js +2 -2
  129. package/lib/public/js/components/pairings.js +14 -14
  130. package/lib/public/js/components/pane-shell.js +2 -2
  131. package/lib/public/js/components/pill-tabs.js +4 -4
  132. package/lib/public/js/components/pop-actions.js +3 -3
  133. package/lib/public/js/components/providers.js +17 -17
  134. package/lib/public/js/components/routes/agents-route.js +2 -2
  135. package/lib/public/js/components/routes/browse-route.js +2 -2
  136. package/lib/public/js/components/routes/chat-route.js +1094 -0
  137. package/lib/public/js/components/routes/cron-route.js +2 -2
  138. package/lib/public/js/components/routes/doctor-route.js +2 -2
  139. package/lib/public/js/components/routes/envars-route.js +2 -2
  140. package/lib/public/js/components/routes/general-route.js +2 -2
  141. package/lib/public/js/components/routes/index.js +1 -0
  142. package/lib/public/js/components/routes/models-route.js +2 -2
  143. package/lib/public/js/components/routes/nodes-route.js +2 -2
  144. package/lib/public/js/components/routes/providers-route.js +2 -2
  145. package/lib/public/js/components/routes/route-redirect.js +2 -2
  146. package/lib/public/js/components/routes/telegram-route.js +2 -2
  147. package/lib/public/js/components/routes/usage-route.js +2 -2
  148. package/lib/public/js/components/routes/watchdog-route.js +2 -2
  149. package/lib/public/js/components/routes/webhooks-route.js +2 -2
  150. package/lib/public/js/components/scope-picker.js +9 -9
  151. package/lib/public/js/components/secret-input.js +5 -5
  152. package/lib/public/js/components/segmented-control.js +2 -2
  153. package/lib/public/js/components/session-select-field.js +7 -7
  154. package/lib/public/js/components/sidebar-git-panel.js +3 -3
  155. package/lib/public/js/components/sidebar.js +55 -3
  156. package/lib/public/js/components/summary-stat-card.js +3 -3
  157. package/lib/public/js/components/telegram-workspace/index.js +10 -10
  158. package/lib/public/js/components/telegram-workspace/manage.js +36 -36
  159. package/lib/public/js/components/telegram-workspace/onboarding.js +73 -73
  160. package/lib/public/js/components/toast.js +8 -8
  161. package/lib/public/js/components/toggle-switch.js +2 -2
  162. package/lib/public/js/components/tooltip.js +5 -5
  163. package/lib/public/js/components/update-action-button.js +2 -2
  164. package/lib/public/js/components/update-modal.js +9 -9
  165. package/lib/public/js/components/usage-tab/constants.js +2 -2
  166. package/lib/public/js/components/usage-tab/index.js +3 -3
  167. package/lib/public/js/components/usage-tab/overview-section.js +15 -15
  168. package/lib/public/js/components/usage-tab/sessions-section.js +19 -19
  169. package/lib/public/js/components/usage-tab/use-usage-tab.js +2 -2
  170. package/lib/public/js/components/watchdog-tab/console/index.js +22 -8
  171. package/lib/public/js/components/watchdog-tab/console/use-console.js +28 -2
  172. package/lib/public/js/components/watchdog-tab/helpers.js +35 -6
  173. package/lib/public/js/components/watchdog-tab/incidents/index.js +6 -6
  174. package/lib/public/js/components/watchdog-tab/incidents/use-incidents.js +1 -1
  175. package/lib/public/js/components/watchdog-tab/index.js +4 -2
  176. package/lib/public/js/components/watchdog-tab/resource-bar.js +5 -5
  177. package/lib/public/js/components/watchdog-tab/resources/index.js +14 -3
  178. package/lib/public/js/components/watchdog-tab/resources/use-resources.js +1 -1
  179. package/lib/public/js/components/watchdog-tab/settings/index.js +97 -30
  180. package/lib/public/js/components/watchdog-tab/settings/use-settings.js +1 -1
  181. package/lib/public/js/components/watchdog-tab/terminal/index.js +3 -3
  182. package/lib/public/js/components/watchdog-tab/terminal/use-terminal.js +41 -5
  183. package/lib/public/js/components/watchdog-tab/use-watchdog-tab.js +2 -0
  184. package/lib/public/js/components/webhooks/create-webhook-modal/index.js +17 -17
  185. package/lib/public/js/components/webhooks/helpers.js +3 -3
  186. package/lib/public/js/components/webhooks/index.js +4 -4
  187. package/lib/public/js/components/webhooks/request-history/index.js +14 -14
  188. package/lib/public/js/components/webhooks/request-history/use-request-history.js +1 -1
  189. package/lib/public/js/components/webhooks/webhook-detail/index.js +41 -41
  190. package/lib/public/js/components/webhooks/webhook-detail/use-webhook-detail.js +1 -1
  191. package/lib/public/js/components/webhooks/webhook-list/index.js +11 -11
  192. package/lib/public/js/components/webhooks/webhook-list/use-webhook-list.js +1 -1
  193. package/lib/public/js/components/welcome/index.js +3 -3
  194. package/lib/public/js/components/welcome/use-welcome.js +10 -10
  195. package/lib/public/js/hooks/use-app-shell-controller.js +1 -1
  196. package/lib/public/js/hooks/use-app-shell-ui.js +1 -1
  197. package/lib/public/js/hooks/use-browse-navigation.js +14 -3
  198. package/lib/public/js/hooks/use-cached-fetch.js +1 -1
  199. package/lib/public/js/hooks/use-destination-session-selection.js +1 -1
  200. package/lib/public/js/hooks/use-hash-location.js +1 -1
  201. package/lib/public/js/hooks/useAgentSessions.js +1 -1
  202. package/lib/public/js/hooks/usePolling.js +1 -1
  203. package/lib/public/js/lib/app-navigation.js +1 -0
  204. package/lib/public/js/lib/storage-keys.js +3 -0
  205. package/lib/public/js/tailwind-config.js +39 -0
  206. package/lib/public/login.html +3 -18
  207. package/lib/public/setup.html +3 -18
  208. package/lib/server/auth-profiles.js +1 -1
  209. package/lib/server/chat-ws.js +835 -0
  210. package/lib/server/init/register-server-routes.js +2 -0
  211. package/lib/server/onboarding/validation.js +15 -10
  212. package/lib/server/routes/nodes.js +10 -2
  213. package/lib/server/routes/pairings.js +5 -1
  214. package/lib/server/routes/system.js +5 -0
  215. package/lib/server/routes/watchdog.js +15 -0
  216. package/lib/server/watchdog-terminal-ws.js +14 -1
  217. package/lib/server/watchdog.js +137 -51
  218. package/lib/server.js +38 -0
  219. package/package.json +14 -3
@@ -1,4 +1,4 @@
1
- import { useEffect, useRef, useState } from "https://esm.sh/preact/hooks";
1
+ import { useEffect, useRef, useState } from "preact/hooks";
2
2
  import { closeWatchdogTerminalSession } from "../../../lib/api.js";
3
3
  import { showToast } from "../../toast.js";
4
4
  import {
@@ -8,6 +8,33 @@ import {
8
8
  loadXtermModules,
9
9
  } from "../helpers.js";
10
10
 
11
+ const waitForTerminalHost = ({
12
+ hostRef = null,
13
+ panelRef = null,
14
+ maxFrames = 8,
15
+ } = {}) =>
16
+ new Promise((resolve, reject) => {
17
+ let framesRemaining = Math.max(1, Number(maxFrames) || 1);
18
+
19
+ const check = () => {
20
+ if (hostRef?.current && panelRef?.current) {
21
+ resolve({
22
+ hostElement: hostRef.current,
23
+ panelElement: panelRef.current,
24
+ });
25
+ return;
26
+ }
27
+ framesRemaining -= 1;
28
+ if (framesRemaining <= 0) {
29
+ reject(new Error("Terminal host not ready"));
30
+ return;
31
+ }
32
+ window.requestAnimationFrame(check);
33
+ };
34
+
35
+ check();
36
+ });
37
+
11
38
  export const useWatchdogTerminal = ({
12
39
  active = false,
13
40
  panelRef = null,
@@ -37,9 +64,14 @@ export const useWatchdogTerminal = ({
37
64
  try {
38
65
  setConnectingTerminal(true);
39
66
  ensureXtermStylesheet();
40
- const [{ Terminal }, { FitAddon }] = await loadXtermModules();
67
+ const { Terminal, FitAddon } = await loadXtermModules();
41
68
  if (cancelled) return;
42
- if (!terminalInstanceRef.current && hostRef?.current) {
69
+ const { hostElement } = await waitForTerminalHost({
70
+ hostRef,
71
+ panelRef,
72
+ });
73
+ if (cancelled) return;
74
+ if (!terminalInstanceRef.current) {
43
75
  const terminal = new Terminal({
44
76
  cursorBlink: true,
45
77
  fontFamily:
@@ -56,7 +88,7 @@ export const useWatchdogTerminal = ({
56
88
  });
57
89
  const fitAddon = new FitAddon();
58
90
  terminal.loadAddon(fitAddon);
59
- terminal.open(hostRef.current);
91
+ terminal.open(hostElement);
60
92
  fitAddon.fit();
61
93
  terminal.attachCustomKeyEventHandler((event) => {
62
94
  if (event.type !== "keydown") return true;
@@ -161,12 +193,16 @@ export const useWatchdogTerminal = ({
161
193
  setTerminalStatusText("Connection error");
162
194
  showToast("Watchdog terminal connection failed", "error");
163
195
  };
164
- } catch {
196
+ } catch (error) {
165
197
  if (cancelled) return;
166
198
  setConnectingTerminal(false);
167
199
  setTerminalUiSettling(false);
168
200
  setTerminalConnected(false);
169
201
  setTerminalStatusText("Terminal failed to load");
202
+ console.error(
203
+ `[watchdog-terminal] initialization failed: ${error?.message || "unknown error"}`,
204
+ error,
205
+ );
170
206
  showToast("Could not initialize terminal", "error");
171
207
  }
172
208
  };
@@ -36,6 +36,7 @@ export const useWatchdogTab = ({
36
36
  isRepairInProgress: settings.isRepairInProgress,
37
37
  logs: consoleState.logs,
38
38
  loadingLogs: consoleState.loadingLogs,
39
+ copyingAll: consoleState.copyingAll,
39
40
  stickToBottom: consoleState.stickToBottom,
40
41
  setStickToBottom: consoleState.setStickToBottom,
41
42
  activeConsoleTab: consoleState.activeConsoleTab,
@@ -51,5 +52,6 @@ export const useWatchdogTab = ({
51
52
  terminalPanelRef: consoleState.terminalPanelRef,
52
53
  terminalHostRef: consoleState.terminalHostRef,
53
54
  terminalInstanceRef: consoleState.terminalInstanceRef,
55
+ onCopyAll: consoleState.onCopyAll,
54
56
  };
55
57
  };
@@ -1,5 +1,5 @@
1
- import { h } from "https://esm.sh/preact";
2
- import htm from "https://esm.sh/htm";
1
+ import { h } from "preact";
2
+ import htm from "htm";
3
3
  import {
4
4
  kNoDestinationSessionValue,
5
5
  useDestinationSessionSelection,
@@ -61,18 +61,18 @@ export const CreateWebhookModal = ({
61
61
  class="h-8 w-8 inline-flex items-center justify-center rounded-lg ac-btn-secondary"
62
62
  aria-label="Close modal"
63
63
  >
64
- <${CloseIcon} className="w-3.5 h-3.5 text-gray-300" />
64
+ <${CloseIcon} className="w-3.5 h-3.5 text-body" />
65
65
  </button>
66
66
  `}
67
67
  />
68
68
  <div class="space-y-2">
69
- <p class="text-xs text-gray-500">Endpoint mode</p>
69
+ <p class="text-xs text-fg-muted">Endpoint mode</p>
70
70
  <div class="flex items-center gap-2">
71
71
  <button
72
72
  class="text-xs px-2 py-1 rounded border transition-colors ${mode ===
73
73
  "webhook"
74
- ? "border-cyan-400 text-cyan-200 bg-cyan-400/10"
75
- : "border-border text-gray-400 hover:text-gray-200"}"
74
+ ? "border-cyan-400 text-status-info bg-cyan-400/10"
75
+ : "border-border text-fg-muted hover:text-body"}"
76
76
  onclick=${() => onModeChange("webhook")}
77
77
  >
78
78
  Webhook
@@ -80,8 +80,8 @@ export const CreateWebhookModal = ({
80
80
  <button
81
81
  class="text-xs px-2 py-1 rounded border transition-colors ${mode ===
82
82
  "oauth"
83
- ? "border-cyan-400 text-cyan-200 bg-cyan-400/10"
84
- : "border-border text-gray-400 hover:text-gray-200"}"
83
+ ? "border-cyan-400 text-status-info bg-cyan-400/10"
84
+ : "border-border text-fg-muted hover:text-body"}"
85
85
  onclick=${() => onModeChange("oauth")}
86
86
  >
87
87
  OAuth Callback
@@ -89,7 +89,7 @@ export const CreateWebhookModal = ({
89
89
  </div>
90
90
  </div>
91
91
  <div class="space-y-2">
92
- <p class="text-xs text-gray-500">Name</p>
92
+ <p class="text-xs text-fg-muted">Name</p>
93
93
  <input
94
94
  type="text"
95
95
  value=${name}
@@ -101,7 +101,7 @@ export const CreateWebhookModal = ({
101
101
  }
102
102
  if (e.key === "Escape") onClose();
103
103
  }}
104
- class="w-full bg-black/30 border border-border rounded-lg px-3 py-1.5 text-sm text-gray-200 outline-none focus:border-gray-500 font-mono"
104
+ class="w-full bg-field border border-border rounded-lg px-3 py-1.5 text-sm text-body outline-none focus:border-fg-muted font-mono"
105
105
  />
106
106
  </div>
107
107
  <${SessionSelectField}
@@ -122,20 +122,20 @@ export const CreateWebhookModal = ({
122
122
  <table class="w-full text-xs">
123
123
  <tbody>
124
124
  <tr class="border-b border-border">
125
- <td class="w-24 px-3 py-2 text-gray-500">Path</td>
126
- <td class="px-3 py-2 text-gray-300 font-mono">
125
+ <td class="w-24 px-3 py-2 text-fg-muted">Path</td>
126
+ <td class="px-3 py-2 text-body font-mono">
127
127
  <code>${previewPath}</code>
128
128
  </td>
129
129
  </tr>
130
130
  <tr class="border-b border-border">
131
- <td class="w-24 px-3 py-2 text-gray-500">URL</td>
132
- <td class="px-3 py-2 text-gray-300 font-mono break-all">
131
+ <td class="w-24 px-3 py-2 text-fg-muted">URL</td>
132
+ <td class="px-3 py-2 text-body font-mono break-all">
133
133
  <code>${previewUrl}</code>
134
134
  </td>
135
135
  </tr>
136
136
  <tr>
137
- <td class="w-24 px-3 py-2 text-gray-500">Transform</td>
138
- <td class="px-3 py-2 text-gray-300 font-mono">
137
+ <td class="w-24 px-3 py-2 text-fg-muted">Transform</td>
138
+ <td class="px-3 py-2 text-body font-mono">
139
139
  <code>hooks/transforms/${previewName}/${previewName}-transform.mjs</code>
140
140
  </td>
141
141
  </tr>
@@ -145,7 +145,7 @@ export const CreateWebhookModal = ({
145
145
  ${mode === "oauth"
146
146
  ? html`
147
147
  <div class="space-y-1">
148
- <p class="text-xs text-gray-500">
148
+ <p class="text-xs text-fg-muted">
149
149
  For OAuth providers that can't send auth headers. AlphaClaw
150
150
  injects webhook auth before forwarding to /hooks/{name}.
151
151
  </p>
@@ -32,18 +32,18 @@ export const getRequestStatusTone = (status) => {
32
32
  if (status === "success") {
33
33
  return {
34
34
  dotClass: "bg-green-500/90",
35
- textClass: "text-green-500/90",
35
+ textClass: "text-status-success-muted/90",
36
36
  };
37
37
  }
38
38
  if (status === "error") {
39
39
  return {
40
40
  dotClass: "bg-red-500/90",
41
- textClass: "text-red-500/90",
41
+ textClass: "text-status-error-muted",
42
42
  };
43
43
  }
44
44
  return {
45
45
  dotClass: "bg-gray-500/70",
46
- textClass: "text-gray-400",
46
+ textClass: "text-fg-muted",
47
47
  };
48
48
  };
49
49
 
@@ -1,6 +1,6 @@
1
- import { h } from "https://esm.sh/preact";
2
- import { useCallback, useMemo, useState } from "https://esm.sh/preact/hooks";
3
- import htm from "https://esm.sh/htm";
1
+ import { h } from "preact";
2
+ import { useCallback, useMemo, useState } from "preact/hooks";
3
+ import htm from "htm";
4
4
  import { createWebhook } from "../../lib/api.js";
5
5
  import { ActionButton } from "../action-button.js";
6
6
  import { PageHeader } from "../page-header.js";
@@ -79,7 +79,7 @@ export const Webhooks = ({
79
79
  leading=${selectedHookName
80
80
  ? html`
81
81
  <button
82
- class="flex items-center gap-1.5 text-sm text-gray-500 hover:text-gray-300 transition-colors"
82
+ class="flex items-center gap-1.5 text-sm text-fg-muted hover:text-body transition-colors"
83
83
  onclick=${onBackToList}
84
84
  >
85
85
  <svg
@@ -1,6 +1,6 @@
1
- import { h } from "https://esm.sh/preact";
2
- import { useMemo } from "https://esm.sh/preact/hooks";
3
- import htm from "https://esm.sh/htm";
1
+ import { h } from "preact";
2
+ import { useMemo } from "preact/hooks";
3
+ import htm from "htm";
4
4
  import { sendAgentMessage } from "../../../lib/api.js";
5
5
  import { ActionButton } from "../../action-button.js";
6
6
  import { AgentSendModal } from "../../agent-send-modal.js";
@@ -63,8 +63,8 @@ export const RequestHistory = ({
63
63
  (filter) => html`
64
64
  <button
65
65
  class="text-xs px-2 py-1 rounded border ${statusFilter === filter
66
- ? "border-cyan-400 text-cyan-200 bg-cyan-400/10"
67
- : "border-border text-gray-400 hover:text-gray-200"}"
66
+ ? "border-cyan-400 text-status-info bg-cyan-400/10"
67
+ : "border-border text-fg-muted hover:text-body"}"
68
68
  onclick=${() => actions.handleSetStatusFilter(filter)}
69
69
  >
70
70
  ${filter}
@@ -75,7 +75,7 @@ export const RequestHistory = ({
75
75
  </div>
76
76
 
77
77
  ${requests.length === 0
78
- ? html`<p class="text-sm text-gray-500">No requests logged yet.</p>`
78
+ ? html`<p class="text-sm text-fg-muted">No requests logged yet.</p>`
79
79
  : html`
80
80
  <div class="ac-history-list">
81
81
  ${requests.map((item) => {
@@ -93,12 +93,12 @@ export const RequestHistory = ({
93
93
  <span class="ac-history-toggle shrink-0" aria-hidden="true"
94
94
  >▸</span
95
95
  >
96
- <span class="truncate text-xs text-gray-300">
96
+ <span class="truncate text-xs text-body">
97
97
  ${formatLastReceived(item.createdAt)}
98
98
  </span>
99
99
  </span>
100
100
  <span class="inline-flex items-center gap-2 shrink-0">
101
- <span class="text-xs text-gray-500"
101
+ <span class="text-xs text-fg-muted"
102
102
  >${formatBytes(item.payloadSize)}</span
103
103
  >
104
104
  <span class=${`text-xs font-medium ${statusTone.textClass}`}
@@ -118,9 +118,9 @@ export const RequestHistory = ({
118
118
  ? html`
119
119
  <div class="ac-history-body space-y-3">
120
120
  <div>
121
- <p class="text-[11px] text-gray-500 mb-1">Headers</p>
121
+ <p class="text-[11px] text-fg-muted mb-1">Headers</p>
122
122
  <pre
123
- class="text-xs bg-black/30 border border-border rounded p-2 overflow-auto"
123
+ class="text-xs bg-field border border-border rounded p-2 overflow-auto"
124
124
  >
125
125
  ${jsonPretty(item.headers)}</pre
126
126
  >
@@ -138,11 +138,11 @@ ${jsonPretty(item.headers)}</pre
138
138
  </div>
139
139
  </div>
140
140
  <div>
141
- <p class="text-[11px] text-gray-500 mb-1">
141
+ <p class="text-[11px] text-fg-muted mb-1">
142
142
  Payload ${item.payloadTruncated ? "(truncated)" : ""}
143
143
  </p>
144
144
  <pre
145
- class="text-xs bg-black/30 border border-border rounded p-2 overflow-auto"
145
+ class="text-xs bg-field border border-border rounded p-2 overflow-auto"
146
146
  >
147
147
  ${jsonPretty(item.payload)}</pre
148
148
  >
@@ -173,11 +173,11 @@ ${jsonPretty(item.payload)}</pre
173
173
  </div>
174
174
  </div>
175
175
  <div>
176
- <p class="text-[11px] text-gray-500 mb-1">
176
+ <p class="text-[11px] text-fg-muted mb-1">
177
177
  Gateway response (${item.gatewayStatus || "n/a"})
178
178
  </p>
179
179
  <pre
180
- class="text-xs bg-black/30 border border-border rounded p-2 overflow-auto"
180
+ class="text-xs bg-field border border-border rounded p-2 overflow-auto"
181
181
  >
182
182
  ${jsonPretty(item.gatewayBody)}</pre
183
183
  >
@@ -1,4 +1,4 @@
1
- import { useCallback, useEffect, useMemo, useState } from "https://esm.sh/preact/hooks";
1
+ import { useCallback, useEffect, useMemo, useState } from "preact/hooks";
2
2
  import {
3
3
  fetchWebhookRequest,
4
4
  fetchWebhookRequests,
@@ -1,6 +1,6 @@
1
- import { h } from "https://esm.sh/preact";
2
- import { useCallback, useState } from "https://esm.sh/preact/hooks";
3
- import htm from "https://esm.sh/htm";
1
+ import { h } from "preact";
2
+ import { useCallback, useState } from "preact/hooks";
3
+ import htm from "htm";
4
4
  import { ActionButton } from "../../action-button.js";
5
5
  import { Badge } from "../../badge.js";
6
6
  import { ConfirmDialog } from "../../confirm-dialog.js";
@@ -70,29 +70,29 @@ export const WebhookDetail = ({
70
70
  </div>
71
71
 
72
72
  ${isWebhookLoading
73
- ? html`<div class="bg-black/20 border border-border rounded-lg p-3">
74
- <p class="text-xs text-gray-500">Loading webhook details...</p>
73
+ ? html`<div class="bg-field border border-border rounded-lg p-3">
74
+ <p class="text-xs text-fg-muted">Loading webhook details...</p>
75
75
  </div>`
76
76
  : webhookLoadError
77
- ? html`<div class="bg-black/20 border border-border rounded-lg p-3">
78
- <p class="text-xs text-red-300">
77
+ ? html`<div class="bg-field border border-border rounded-lg p-3">
78
+ <p class="text-xs text-status-error">
79
79
  ${webhookLoadError?.message || "Could not load webhook details"}
80
80
  </p>
81
81
  </div>`
82
82
  : hasOauthCallback
83
83
  ? null
84
- : html`<div class="bg-black/20 border border-border rounded-lg p-3 space-y-4">
84
+ : html`<div class="bg-field border border-border rounded-lg p-3 space-y-4">
85
85
  ${selectedWebhookManaged
86
86
  ? null
87
87
  : html`
88
88
  <div class="space-y-2">
89
- <p class="text-xs text-gray-500">Auth mode</p>
89
+ <p class="text-xs text-fg-muted">Auth mode</p>
90
90
  <div class="flex items-center gap-2">
91
91
  <button
92
92
  class="text-xs px-2 py-1 rounded border transition-colors ${authMode ===
93
93
  "headers"
94
- ? "border-cyan-400 text-cyan-200 bg-cyan-400/10"
95
- : "border-border text-gray-400 hover:text-gray-200"}"
94
+ ? "border-cyan-400 text-status-info bg-cyan-400/10"
95
+ : "border-border text-fg-muted hover:text-body"}"
96
96
  onclick=${() => actions.setAuthMode("headers")}
97
97
  >
98
98
  Headers
@@ -100,8 +100,8 @@ export const WebhookDetail = ({
100
100
  <button
101
101
  class="text-xs px-2 py-1 rounded border transition-colors ${authMode ===
102
102
  "query"
103
- ? "border-cyan-400 text-cyan-200 bg-cyan-400/10"
104
- : "border-border text-gray-400 hover:text-gray-200"}"
103
+ ? "border-cyan-400 text-status-info bg-cyan-400/10"
104
+ : "border-border text-fg-muted hover:text-body"}"
105
105
  onclick=${() => actions.setAuthMode("query")}
106
106
  >
107
107
  Query string
@@ -110,7 +110,7 @@ export const WebhookDetail = ({
110
110
  </div>
111
111
  `}
112
112
  <div class="space-y-2">
113
- <p class="text-xs text-gray-500">Webhook URL</p>
113
+ <p class="text-xs text-fg-muted">Webhook URL</p>
114
114
  <div class="flex items-center gap-2">
115
115
  <input
116
116
  type="text"
@@ -118,7 +118,7 @@ export const WebhookDetail = ({
118
118
  value=${effectiveAuthMode === "query"
119
119
  ? webhookUrlWithQueryToken
120
120
  : webhookUrl}
121
- class="h-8 flex-1 bg-black/30 border border-border rounded-lg px-3 text-xs text-gray-200 outline-none font-mono"
121
+ class="h-8 flex-1 bg-field border border-border rounded-lg px-3 text-xs text-body outline-none font-mono"
122
122
  />
123
123
  <button
124
124
  class="h-8 text-xs px-2.5 rounded-lg ac-btn-secondary shrink-0"
@@ -144,13 +144,13 @@ export const WebhookDetail = ({
144
144
  : effectiveAuthMode === "headers"
145
145
  ? html`
146
146
  <div class="space-y-2">
147
- <p class="text-xs text-gray-500">Auth headers</p>
147
+ <p class="text-xs text-fg-muted">Auth headers</p>
148
148
  <div class="flex items-center gap-2">
149
149
  <input
150
150
  type="text"
151
151
  readonly
152
152
  value=${authHeaderValue}
153
- class="h-8 flex-1 bg-black/30 border border-border rounded-lg px-3 text-xs text-gray-200 outline-none font-mono"
153
+ class="h-8 flex-1 bg-field border border-border rounded-lg px-3 text-xs text-body outline-none font-mono"
154
154
  />
155
155
  <button
156
156
  class="h-8 text-xs px-2.5 rounded-lg ac-btn-secondary shrink-0"
@@ -171,7 +171,7 @@ export const WebhookDetail = ({
171
171
  </div>
172
172
  `
173
173
  : html`
174
- <p class="text-xs text-yellow-300">
174
+ <p class="text-xs text-status-warning">
175
175
  Always use auth headers when possible. Query string is
176
176
  less secure.
177
177
  </p>
@@ -181,9 +181,9 @@ export const WebhookDetail = ({
181
181
  ${isWebhookLoading || webhookLoadError || selectedWebhookManaged || !hasOauthCallback
182
182
  ? null
183
183
  : html`
184
- <div class="bg-black/20 border border-border rounded-lg p-3 space-y-2">
184
+ <div class="bg-field border border-border rounded-lg p-3 space-y-2">
185
185
  <div class="flex items-center gap-2">
186
- <p class="text-xs text-gray-500">OAuth Callback URL</p>
186
+ <p class="text-xs text-fg-muted">OAuth Callback URL</p>
187
187
  ${hasOauthCallback
188
188
  ? html`<${Badge} tone="neutral">OAuth alias</${Badge}>`
189
189
  : null}
@@ -193,7 +193,7 @@ export const WebhookDetail = ({
193
193
  type="text"
194
194
  readonly
195
195
  value=${hasOauthCallback ? oauthCallbackUrl : "Not enabled"}
196
- class="h-8 flex-1 bg-black/30 border border-border rounded-lg px-3 text-xs text-gray-200 outline-none font-mono"
196
+ class="h-8 flex-1 bg-field border border-border rounded-lg px-3 text-xs text-body outline-none font-mono"
197
197
  />
198
198
  ${hasOauthCallback
199
199
  ? html`
@@ -228,26 +228,26 @@ export const WebhookDetail = ({
228
228
  ${rotatingOauthCallback ? "Rotating..." : "Rotate"}
229
229
  </button>
230
230
  </div>
231
- <p class="text-xs text-yellow-300">
231
+ <p class="text-xs text-status-warning">
232
232
  Keep this URL private. Rotate if exposed.
233
233
  </p>
234
234
  </div>
235
235
  </div>
236
236
  `}
237
237
 
238
- <div class="bg-black/20 border border-border rounded-lg p-3 space-y-2">
238
+ <div class="bg-field border border-border rounded-lg p-3 space-y-2">
239
239
  ${selectedWebhookManaged
240
240
  ? html`
241
- <p class="text-xs text-gray-500">Deliver to</p>
242
- <p class="text-xs text-gray-200 font-mono">
241
+ <p class="text-xs text-fg-muted">Deliver to</p>
242
+ <p class="text-xs text-body font-mono">
243
243
  ${selectedDeliveryAgentName}${" "}
244
- <span class="text-xs text-gray-500 font-mono"
244
+ <span class="text-xs text-fg-muted font-mono"
245
245
  >(${selectedDeliveryChannel})</span
246
246
  >
247
247
  </p>
248
248
  `
249
249
  : html`
250
- <p class="text-xs text-gray-500">Deliver to</p>
250
+ <p class="text-xs text-fg-muted">Deliver to</p>
251
251
  <div class="flex items-center gap-2">
252
252
  <select
253
253
  value=${destinationSessionKey || kNoDestinationSessionValue}
@@ -258,7 +258,7 @@ export const WebhookDetail = ({
258
258
  );
259
259
  }}
260
260
  disabled=${loadingDestinationSessions || savingDestination}
261
- class="h-8 flex-1 bg-black/30 border border-border rounded-lg px-3 text-xs text-gray-200 focus:border-gray-500"
261
+ class="h-8 flex-1 bg-field border border-border rounded-lg px-3 text-xs text-body focus:border-fg-muted"
262
262
  >
263
263
  <option value=${kNoDestinationSessionValue}>Default</option>
264
264
  ${loadingDestinationSessions
@@ -287,19 +287,19 @@ export const WebhookDetail = ({
287
287
  />
288
288
  </div>
289
289
  ${destinationLoadError
290
- ? html`<p class="text-xs text-red-400">${destinationLoadError}</p>`
290
+ ? html`<p class="text-xs text-status-error-muted">${destinationLoadError}</p>`
291
291
  : null}
292
292
  `}
293
293
  </div>
294
294
 
295
- <div class="bg-black/20 border border-border rounded-lg p-3 space-y-2">
296
- <p class="text-xs text-gray-500">Test webhook</p>
295
+ <div class="bg-field border border-border rounded-lg p-3 space-y-2">
296
+ <p class="text-xs text-fg-muted">Test webhook</p>
297
297
  <div class="flex flex-col gap-2 sm:flex-row sm:items-center">
298
298
  <input
299
299
  type="text"
300
300
  readonly
301
301
  value=${activeCurlCommand}
302
- class="h-8 w-full sm:flex-1 sm:min-w-0 bg-black/30 border border-border rounded-lg px-3 text-xs text-gray-200 outline-none font-mono overflow-x-auto scrollbar-hidden"
302
+ class="h-8 w-full sm:flex-1 sm:min-w-0 bg-field border border-border rounded-lg px-3 text-xs text-body outline-none font-mono overflow-x-auto scrollbar-hidden"
303
303
  />
304
304
  <div class="grid grid-cols-2 gap-2 w-full sm:w-auto sm:flex sm:items-center">
305
305
  <button
@@ -326,9 +326,9 @@ export const WebhookDetail = ({
326
326
  </div>
327
327
  </div>
328
328
 
329
- <div class="bg-black/20 border border-border rounded-lg p-3">
330
- <div class="flex items-center gap-2 text-xs text-gray-300">
331
- <span class="text-gray-500">Transform:</span>
329
+ <div class="bg-field border border-border rounded-lg p-3">
330
+ <div class="flex items-center gap-2 text-xs text-body">
331
+ <span class="text-fg-muted">Transform:</span>
332
332
  ${selectedWebhook?.transformPath
333
333
  ? html`<button
334
334
  type="button"
@@ -342,8 +342,8 @@ export const WebhookDetail = ({
342
342
  <span
343
343
  class=${`ml-auto inline-flex items-center gap-1 px-1.5 py-0.5 rounded border font-sans ${
344
344
  selectedWebhook?.transformExists
345
- ? "border-green-500/30 text-green-300 bg-green-500/10"
346
- : "border-yellow-500/30 text-yellow-300 bg-yellow-500/10"
345
+ ? "border-green-500/30 text-status-success bg-green-500/10"
346
+ : "border-yellow-500/30 text-status-warning bg-yellow-500/10"
347
347
  }`}
348
348
  >
349
349
  <span class="font-sans text-sm leading-none">
@@ -355,7 +355,7 @@ export const WebhookDetail = ({
355
355
  </div>
356
356
 
357
357
  <div class="flex items-center justify-between gap-3">
358
- <p class="text-xs text-gray-600">
358
+ <p class="text-xs text-fg-dim">
359
359
  Created: ${formatDateTime(selectedWebhook?.createdAt)}
360
360
  </p>
361
361
  ${selectedWebhookManaged
@@ -380,7 +380,7 @@ export const WebhookDetail = ({
380
380
  ${selectedWebhookManaged && !isWebhookLoading && !webhookLoadError
381
381
  ? html`
382
382
  <div class="rounded-lg border border-yellow-500/30 bg-yellow-500/10 p-3">
383
- <p class="text-xs text-yellow-200">
383
+ <p class="text-xs text-status-warning">
384
384
  This webhook is managed by Gmail Watch setup and cannot be
385
385
  deleted or edited from this page.
386
386
  </p>
@@ -420,8 +420,8 @@ export const WebhookDetail = ({
420
420
  title="Delete webhook?"
421
421
  message=${`This removes "/hooks/${selectedHookName}" from openclaw.json.`}
422
422
  details=${html`
423
- <div class="rounded-lg border border-border bg-black/20 p-3">
424
- <label class="flex items-center gap-2 text-xs text-gray-300 select-none">
423
+ <div class="rounded-lg border border-border bg-field p-3">
424
+ <label class="flex items-center gap-2 text-xs text-body select-none">
425
425
  <input
426
426
  type="checkbox"
427
427
  checked=${deleteTransformDir}
@@ -3,7 +3,7 @@ import {
3
3
  useEffect,
4
4
  useMemo,
5
5
  useState,
6
- } from "https://esm.sh/preact/hooks";
6
+ } from "preact/hooks";
7
7
  import {
8
8
  deleteWebhook,
9
9
  fetchAgents,
@@ -1,5 +1,5 @@
1
- import { h } from "https://esm.sh/preact";
2
- import htm from "https://esm.sh/htm";
1
+ import { h } from "preact";
2
+ import htm from "htm";
3
3
  import { Badge } from "../../badge.js";
4
4
  import { formatLastReceived, healthClassName } from "../helpers.js";
5
5
  import { useWebhookList } from "./use-webhook-list.js";
@@ -16,10 +16,10 @@ export const WebhookList = ({
16
16
  return html`
17
17
  <div class="bg-surface border border-border rounded-xl p-4 space-y-4">
18
18
  ${isListLoading
19
- ? html`<p class="text-xs text-gray-500">Loading webhooks...</p>`
19
+ ? html`<p class="text-xs text-fg-muted">Loading webhooks...</p>`
20
20
  : null}
21
21
  ${!isListLoading && webhooks.length === 0
22
- ? html`<p class="text-sm text-gray-500">
22
+ ? html`<p class="text-sm text-fg-muted">
23
23
  No webhooks configured yet. Create one to get started.
24
24
  </p>`
25
25
  : null}
@@ -28,7 +28,7 @@ export const WebhookList = ({
28
28
  <div class="overflow-auto">
29
29
  <table class="w-full text-sm">
30
30
  <thead>
31
- <tr class="text-left text-xs text-gray-500 border-b border-border">
31
+ <tr class="text-left text-xs text-fg-muted border-b border-border">
32
32
  <th class="pb-2 pr-3">Path</th>
33
33
  <th class="pb-2 pr-3">Last received</th>
34
34
  <th class="pb-2 pr-3">Errors</th>
@@ -47,22 +47,22 @@ export const WebhookList = ({
47
47
  onclick=${() => actions.handleSelectHook(item.name)}
48
48
  >
49
49
  <td
50
- class="px-3 py-2.5 group-hover:bg-white/5 first:rounded-l-lg transition-colors"
50
+ class="px-3 py-2.5 group-hover:bg-surface first:rounded-l-lg transition-colors"
51
51
  >
52
52
  <code>${item.path || `/hooks/${item.name}`}</code>
53
53
  </td>
54
54
  <td
55
- class="px-3 py-2.5 text-xs text-gray-400 group-hover:bg-white/5 transition-colors"
55
+ class="px-3 py-2.5 text-xs text-fg-muted group-hover:bg-surface transition-colors"
56
56
  >
57
57
  ${formatLastReceived(item.lastReceived)}
58
58
  </td>
59
59
  <td
60
- class="px-3 py-2.5 text-xs group-hover:bg-white/5 transition-colors"
60
+ class="px-3 py-2.5 text-xs group-hover:bg-surface transition-colors"
61
61
  >
62
62
  ${item.errorCount || 0}
63
63
  </td>
64
64
  <td
65
- class="px-3 py-2.5 group-hover:bg-white/5 last:rounded-r-lg transition-colors"
65
+ class="px-3 py-2.5 group-hover:bg-surface last:rounded-r-lg transition-colors"
66
66
  >
67
67
  <span
68
68
  class="inline-block w-2.5 h-2.5 rounded-full ${healthClassName(
@@ -72,11 +72,11 @@ export const WebhookList = ({
72
72
  />
73
73
  </td>
74
74
  <td
75
- class="px-3 py-2.5 text-xs text-gray-400 group-hover:bg-white/5 transition-colors"
75
+ class="px-3 py-2.5 text-xs text-fg-muted group-hover:bg-surface transition-colors"
76
76
  >
77
77
  ${item.managed
78
78
  ? html`<span
79
- class="inline-flex items-center rounded-full px-2 py-0.5 text-[11px] bg-cyan-500/10 text-cyan-200"
79
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-[11px] bg-cyan-500/10 text-status-info"
80
80
  >Managed</span
81
81
  >`
82
82
  : item.oauthCallbackEnabled