@chrysb/alphaclaw 0.8.1 → 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.
Files changed (209) hide show
  1. package/README.md +32 -24
  2. package/bin/alphaclaw.js +13 -2
  3. package/lib/public/css/tailwind.generated.css +1 -0
  4. package/lib/public/css/tailwind.input.css +3 -0
  5. package/lib/public/css/theme.css +28 -0
  6. package/lib/public/css/vendor/xterm.css +218 -0
  7. package/lib/public/dist/app.bundle.js +10514 -0
  8. package/lib/public/dist/chunks/addon-fit-W4YZGRNV.js +1 -0
  9. package/lib/public/dist/chunks/chunk-72ZECFVW.js +1 -0
  10. package/lib/public/dist/chunks/xterm-KOX4YMOF.js +9 -0
  11. package/lib/public/js/app.js +4 -4
  12. package/lib/public/js/components/action-button.js +8 -8
  13. package/lib/public/js/components/add-channel-menu.js +2 -2
  14. package/lib/public/js/components/agent-send-modal.js +6 -6
  15. package/lib/public/js/components/agents-tab/agent-bindings-section/channel-item-trailing.js +7 -7
  16. package/lib/public/js/components/agents-tab/agent-bindings-section/index.js +3 -3
  17. package/lib/public/js/components/agents-tab/agent-bindings-section/use-agent-bindings.js +1 -1
  18. package/lib/public/js/components/agents-tab/agent-bindings-section/use-channel-items.js +4 -4
  19. package/lib/public/js/components/agents-tab/agent-detail-panel.js +5 -5
  20. package/lib/public/js/components/agents-tab/agent-identity-section.js +18 -18
  21. package/lib/public/js/components/agents-tab/agent-overview/index.js +2 -2
  22. package/lib/public/js/components/agents-tab/agent-overview/manage-card.js +2 -2
  23. package/lib/public/js/components/agents-tab/agent-overview/model-card.js +8 -8
  24. package/lib/public/js/components/agents-tab/agent-overview/tools-card.js +5 -5
  25. package/lib/public/js/components/agents-tab/agent-overview/use-model-card.js +1 -1
  26. package/lib/public/js/components/agents-tab/agent-overview/use-workspace-card.js +1 -1
  27. package/lib/public/js/components/agents-tab/agent-overview/workspace-card.js +4 -4
  28. package/lib/public/js/components/agents-tab/agent-pairing-section.js +4 -4
  29. package/lib/public/js/components/agents-tab/agent-tools/index.js +5 -5
  30. package/lib/public/js/components/agents-tab/agent-tools/use-agent-tools.js +1 -1
  31. package/lib/public/js/components/agents-tab/create-agent-modal.js +13 -13
  32. package/lib/public/js/components/agents-tab/create-channel-modal.js +34 -34
  33. package/lib/public/js/components/agents-tab/delete-agent-dialog.js +3 -3
  34. package/lib/public/js/components/agents-tab/edit-agent-modal.js +9 -9
  35. package/lib/public/js/components/agents-tab/index.js +3 -3
  36. package/lib/public/js/components/agents-tab/use-agents.js +1 -1
  37. package/lib/public/js/components/badge.js +6 -6
  38. package/lib/public/js/components/channel-account-status-badge.js +2 -2
  39. package/lib/public/js/components/channel-operations-panel.js +2 -2
  40. package/lib/public/js/components/channels.js +9 -9
  41. package/lib/public/js/components/confirm-dialog.js +5 -5
  42. package/lib/public/js/components/credentials-modal.js +22 -22
  43. package/lib/public/js/components/cron-tab/cron-calendar.js +6 -6
  44. package/lib/public/js/components/cron-tab/cron-insights-panel.js +10 -10
  45. package/lib/public/js/components/cron-tab/cron-job-detail.js +4 -4
  46. package/lib/public/js/components/cron-tab/cron-job-list.js +4 -4
  47. package/lib/public/js/components/cron-tab/cron-job-settings-card.js +15 -15
  48. package/lib/public/js/components/cron-tab/cron-job-trends-panel.js +5 -5
  49. package/lib/public/js/components/cron-tab/cron-job-usage.js +16 -16
  50. package/lib/public/js/components/cron-tab/cron-overview.js +10 -10
  51. package/lib/public/js/components/cron-tab/cron-prompt-editor.js +3 -3
  52. package/lib/public/js/components/cron-tab/cron-run-history-panel.js +39 -39
  53. package/lib/public/js/components/cron-tab/cron-runs-trend-card.js +4 -4
  54. package/lib/public/js/components/cron-tab/index.js +5 -5
  55. package/lib/public/js/components/cron-tab/use-cron-tab.js +1 -1
  56. package/lib/public/js/components/device-pairings.js +12 -12
  57. package/lib/public/js/components/doctor/findings-list.js +22 -22
  58. package/lib/public/js/components/doctor/fix-card-modal.js +2 -2
  59. package/lib/public/js/components/doctor/general-warning.js +5 -5
  60. package/lib/public/js/components/doctor/index.js +26 -26
  61. package/lib/public/js/components/doctor/summary-cards.js +5 -5
  62. package/lib/public/js/components/envars.js +16 -16
  63. package/lib/public/js/components/features.js +4 -4
  64. package/lib/public/js/components/file-tree.js +4 -4
  65. package/lib/public/js/components/file-viewer/diff-viewer.js +2 -2
  66. package/lib/public/js/components/file-viewer/editor-surface.js +2 -2
  67. package/lib/public/js/components/file-viewer/frontmatter-panel.js +2 -2
  68. package/lib/public/js/components/file-viewer/index.js +3 -3
  69. package/lib/public/js/components/file-viewer/markdown-split-view.js +2 -2
  70. package/lib/public/js/components/file-viewer/media-preview.js +2 -2
  71. package/lib/public/js/components/file-viewer/scroll-sync.js +1 -1
  72. package/lib/public/js/components/file-viewer/sqlite-viewer.js +2 -2
  73. package/lib/public/js/components/file-viewer/status-banners.js +2 -2
  74. package/lib/public/js/components/file-viewer/toolbar.js +2 -2
  75. package/lib/public/js/components/file-viewer/use-editor-line-number-sync.js +1 -1
  76. package/lib/public/js/components/file-viewer/use-editor-selection-restore.js +1 -1
  77. package/lib/public/js/components/file-viewer/use-file-diff.js +1 -1
  78. package/lib/public/js/components/file-viewer/use-file-loader.js +1 -1
  79. package/lib/public/js/components/file-viewer/use-file-viewer-draft-sync.js +1 -1
  80. package/lib/public/js/components/file-viewer/use-file-viewer-hotkeys.js +1 -1
  81. package/lib/public/js/components/file-viewer/use-file-viewer.js +2 -2
  82. package/lib/public/js/components/gateway.js +12 -12
  83. package/lib/public/js/components/general/index.js +7 -7
  84. package/lib/public/js/components/general/use-general-tab.js +1 -1
  85. package/lib/public/js/components/global-restart-banner.js +2 -2
  86. package/lib/public/js/components/google/account-row.js +7 -7
  87. package/lib/public/js/components/google/add-account-modal.js +8 -8
  88. package/lib/public/js/components/google/gmail-setup-wizard.js +24 -24
  89. package/lib/public/js/components/google/gmail-watch-toggle.js +5 -5
  90. package/lib/public/js/components/google/index.js +6 -6
  91. package/lib/public/js/components/google/use-gmail-watch.js +1 -1
  92. package/lib/public/js/components/google/use-google-accounts.js +1 -1
  93. package/lib/public/js/components/icons.js +2 -2
  94. package/lib/public/js/components/info-tooltip.js +3 -3
  95. package/lib/public/js/components/loading-spinner.js +2 -2
  96. package/lib/public/js/components/modal-shell.js +5 -5
  97. package/lib/public/js/components/models-tab/index.js +11 -11
  98. package/lib/public/js/components/models-tab/model-picker.js +9 -9
  99. package/lib/public/js/components/models-tab/provider-auth-card.js +12 -12
  100. package/lib/public/js/components/models-tab/use-models.js +1 -1
  101. package/lib/public/js/components/models.js +18 -18
  102. package/lib/public/js/components/nodes-tab/browser-attach/index.js +5 -5
  103. package/lib/public/js/components/nodes-tab/connected-nodes/index.js +32 -32
  104. package/lib/public/js/components/nodes-tab/connected-nodes/use-connected-nodes-card.js +18 -3
  105. package/lib/public/js/components/nodes-tab/exec-allowlist/index.js +10 -10
  106. package/lib/public/js/components/nodes-tab/exec-allowlist/use-exec-allowlist.js +1 -1
  107. package/lib/public/js/components/nodes-tab/exec-config/index.js +13 -13
  108. package/lib/public/js/components/nodes-tab/exec-config/use-exec-config.js +1 -1
  109. package/lib/public/js/components/nodes-tab/index.js +2 -2
  110. package/lib/public/js/components/nodes-tab/setup-wizard/index.js +14 -14
  111. package/lib/public/js/components/nodes-tab/setup-wizard/use-setup-wizard.js +1 -1
  112. package/lib/public/js/components/nodes-tab/use-nodes-tab.js +1 -1
  113. package/lib/public/js/components/onboarding/use-welcome-codex.js +1 -1
  114. package/lib/public/js/components/onboarding/use-welcome-pairing.js +1 -1
  115. package/lib/public/js/components/onboarding/use-welcome-storage.js +1 -1
  116. package/lib/public/js/components/onboarding/welcome-config.js +3 -3
  117. package/lib/public/js/components/onboarding/welcome-form-step.js +34 -34
  118. package/lib/public/js/components/onboarding/welcome-header.js +2 -2
  119. package/lib/public/js/components/onboarding/welcome-import-step.js +22 -22
  120. package/lib/public/js/components/onboarding/welcome-pairing-step.js +15 -15
  121. package/lib/public/js/components/onboarding/welcome-placeholder-review-step.js +7 -7
  122. package/lib/public/js/components/onboarding/welcome-pre-step.js +9 -9
  123. package/lib/public/js/components/onboarding/welcome-secret-review-step.js +15 -15
  124. package/lib/public/js/components/onboarding/welcome-setup-step.js +8 -8
  125. package/lib/public/js/components/overflow-menu.js +3 -3
  126. package/lib/public/js/components/page-header.js +2 -2
  127. package/lib/public/js/components/pairings.js +14 -14
  128. package/lib/public/js/components/pane-shell.js +2 -2
  129. package/lib/public/js/components/pill-tabs.js +4 -4
  130. package/lib/public/js/components/pop-actions.js +3 -3
  131. package/lib/public/js/components/providers.js +17 -17
  132. package/lib/public/js/components/routes/agents-route.js +2 -2
  133. package/lib/public/js/components/routes/browse-route.js +2 -2
  134. package/lib/public/js/components/routes/cron-route.js +2 -2
  135. package/lib/public/js/components/routes/doctor-route.js +2 -2
  136. package/lib/public/js/components/routes/envars-route.js +2 -2
  137. package/lib/public/js/components/routes/general-route.js +2 -2
  138. package/lib/public/js/components/routes/models-route.js +2 -2
  139. package/lib/public/js/components/routes/nodes-route.js +2 -2
  140. package/lib/public/js/components/routes/providers-route.js +2 -2
  141. package/lib/public/js/components/routes/route-redirect.js +2 -2
  142. package/lib/public/js/components/routes/telegram-route.js +2 -2
  143. package/lib/public/js/components/routes/usage-route.js +2 -2
  144. package/lib/public/js/components/routes/watchdog-route.js +2 -2
  145. package/lib/public/js/components/routes/webhooks-route.js +2 -2
  146. package/lib/public/js/components/scope-picker.js +9 -9
  147. package/lib/public/js/components/secret-input.js +5 -5
  148. package/lib/public/js/components/segmented-control.js +2 -2
  149. package/lib/public/js/components/session-select-field.js +7 -7
  150. package/lib/public/js/components/sidebar-git-panel.js +3 -3
  151. package/lib/public/js/components/sidebar.js +3 -3
  152. package/lib/public/js/components/summary-stat-card.js +3 -3
  153. package/lib/public/js/components/telegram-workspace/index.js +10 -10
  154. package/lib/public/js/components/telegram-workspace/manage.js +36 -36
  155. package/lib/public/js/components/telegram-workspace/onboarding.js +73 -73
  156. package/lib/public/js/components/toast.js +8 -8
  157. package/lib/public/js/components/toggle-switch.js +2 -2
  158. package/lib/public/js/components/tooltip.js +5 -5
  159. package/lib/public/js/components/update-action-button.js +2 -2
  160. package/lib/public/js/components/update-modal.js +9 -9
  161. package/lib/public/js/components/usage-tab/constants.js +2 -2
  162. package/lib/public/js/components/usage-tab/index.js +3 -3
  163. package/lib/public/js/components/usage-tab/overview-section.js +15 -15
  164. package/lib/public/js/components/usage-tab/sessions-section.js +19 -19
  165. package/lib/public/js/components/usage-tab/use-usage-tab.js +2 -2
  166. package/lib/public/js/components/watchdog-tab/console/index.js +22 -8
  167. package/lib/public/js/components/watchdog-tab/console/use-console.js +28 -2
  168. package/lib/public/js/components/watchdog-tab/helpers.js +35 -6
  169. package/lib/public/js/components/watchdog-tab/incidents/index.js +6 -6
  170. package/lib/public/js/components/watchdog-tab/incidents/use-incidents.js +1 -1
  171. package/lib/public/js/components/watchdog-tab/index.js +4 -2
  172. package/lib/public/js/components/watchdog-tab/resource-bar.js +5 -5
  173. package/lib/public/js/components/watchdog-tab/resources/index.js +14 -3
  174. package/lib/public/js/components/watchdog-tab/resources/use-resources.js +1 -1
  175. package/lib/public/js/components/watchdog-tab/settings/index.js +97 -30
  176. package/lib/public/js/components/watchdog-tab/settings/use-settings.js +1 -1
  177. package/lib/public/js/components/watchdog-tab/terminal/index.js +3 -3
  178. package/lib/public/js/components/watchdog-tab/terminal/use-terminal.js +41 -5
  179. package/lib/public/js/components/watchdog-tab/use-watchdog-tab.js +2 -0
  180. package/lib/public/js/components/webhooks/create-webhook-modal/index.js +17 -17
  181. package/lib/public/js/components/webhooks/helpers.js +3 -3
  182. package/lib/public/js/components/webhooks/index.js +4 -4
  183. package/lib/public/js/components/webhooks/request-history/index.js +14 -14
  184. package/lib/public/js/components/webhooks/request-history/use-request-history.js +1 -1
  185. package/lib/public/js/components/webhooks/webhook-detail/index.js +41 -41
  186. package/lib/public/js/components/webhooks/webhook-detail/use-webhook-detail.js +1 -1
  187. package/lib/public/js/components/webhooks/webhook-list/index.js +11 -11
  188. package/lib/public/js/components/webhooks/webhook-list/use-webhook-list.js +1 -1
  189. package/lib/public/js/components/welcome/index.js +3 -3
  190. package/lib/public/js/components/welcome/use-welcome.js +10 -10
  191. package/lib/public/js/hooks/use-app-shell-controller.js +1 -1
  192. package/lib/public/js/hooks/use-app-shell-ui.js +1 -1
  193. package/lib/public/js/hooks/use-browse-navigation.js +1 -1
  194. package/lib/public/js/hooks/use-cached-fetch.js +1 -1
  195. package/lib/public/js/hooks/use-destination-session-selection.js +1 -1
  196. package/lib/public/js/hooks/use-hash-location.js +1 -1
  197. package/lib/public/js/hooks/useAgentSessions.js +1 -1
  198. package/lib/public/js/hooks/usePolling.js +1 -1
  199. package/lib/public/js/tailwind-config.js +39 -0
  200. package/lib/public/login.html +3 -18
  201. package/lib/public/setup.html +2 -18
  202. package/lib/server/init/register-server-routes.js +2 -0
  203. package/lib/server/routes/nodes.js +10 -2
  204. package/lib/server/routes/pairings.js +5 -1
  205. package/lib/server/routes/system.js +5 -0
  206. package/lib/server/routes/watchdog.js +15 -0
  207. package/lib/server/watchdog.js +137 -51
  208. package/lib/server.js +2 -0
  209. package/package.json +14 -3
@@ -1,6 +1,6 @@
1
- import { h } from 'https://esm.sh/preact';
2
- import { useState } from 'https://esm.sh/preact/hooks';
3
- import htm from 'https://esm.sh/htm';
1
+ import { h } from 'preact';
2
+ import { useState } from 'preact/hooks';
3
+ import htm from 'htm';
4
4
  import { ActionButton } from './action-button.js';
5
5
  const html = htm.bind(h);
6
6
 
@@ -36,24 +36,24 @@ const DeviceRow = ({ d, onApprove, onReject }) => {
36
36
 
37
37
  if (busy === 'approve') {
38
38
  return html`
39
- <div class="bg-black/30 rounded-lg p-3 mb-2 flex items-center gap-2">
40
- <span class="text-green-400 text-sm">Approved</span>
41
- <span class="text-gray-500 text-xs">${title}</span>
39
+ <div class="bg-field rounded-lg p-3 mb-2 flex items-center gap-2">
40
+ <span class="text-status-success text-sm">Approved</span>
41
+ <span class="text-fg-muted text-xs">${title}</span>
42
42
  </div>`;
43
43
  }
44
44
  if (busy === 'reject') {
45
45
  return html`
46
- <div class="bg-black/30 rounded-lg p-3 mb-2 flex items-center gap-2">
47
- <span class="text-gray-400 text-sm">Rejected</span>
48
- <span class="text-gray-500 text-xs">${title}</span>
46
+ <div class="bg-field rounded-lg p-3 mb-2 flex items-center gap-2">
47
+ <span class="text-fg-muted text-sm">Rejected</span>
48
+ <span class="text-fg-muted text-xs">${title}</span>
49
49
  </div>`;
50
50
  }
51
51
 
52
52
  return html`
53
- <div class="bg-black/30 rounded-lg p-3 mb-2">
53
+ <div class="bg-field rounded-lg p-3 mb-2">
54
54
  <div class="flex items-center gap-2 mb-2">
55
55
  <span class="font-medium text-sm">${title}</span>
56
- ${subtitle && html`<span class="text-xs text-gray-500">${subtitle}</span>`}
56
+ ${subtitle && html`<span class="text-xs text-fg-muted">${subtitle}</span>`}
57
57
  </div>
58
58
  <div class="flex gap-2">
59
59
  <${ActionButton}
@@ -79,7 +79,7 @@ export const DevicePairings = ({ pending, onApprove, onReject }) => {
79
79
 
80
80
  return html`
81
81
  <div class="mt-3 pt-3 border-t border-border">
82
- <p class="text-xs text-gray-500 mb-2">Pending device pairings</p>
82
+ <p class="text-xs text-fg-muted mb-2">Pending device pairings</p>
83
83
  ${pending.map((d) => html`<${DeviceRow} key=${d.id} d=${d} onApprove=${onApprove} onReject=${onReject} />`)}
84
84
  </div>`;
85
85
  };
@@ -1,6 +1,6 @@
1
- import { h } from "https://esm.sh/preact";
2
- import { useState } from "https://esm.sh/preact/hooks";
3
- import htm from "https://esm.sh/htm";
1
+ import { h } from "preact";
2
+ import { useState } from "preact/hooks";
3
+ import htm from "htm";
4
4
  import { Badge } from "../badge.js";
5
5
  import { ActionButton } from "../action-button.js";
6
6
  import {
@@ -65,7 +65,7 @@ const SnippetBlock = ({ item, onOpenFile, isOutdated }) => {
65
65
  return html`
66
66
  <div class="mt-1.5 rounded-lg border border-border overflow-hidden">
67
67
  <div
68
- class="flex items-center justify-between px-3 py-1.5 bg-black/30 border-b border-border"
68
+ class="flex items-center justify-between px-3 py-1.5 bg-field border-b border-border"
69
69
  >
70
70
  <button
71
71
  type="button"
@@ -81,21 +81,21 @@ const SnippetBlock = ({ item, onOpenFile, isOutdated }) => {
81
81
  ${formatPathLabel(item.path, item.startLine, item.endLine)}
82
82
  </button>
83
83
  ${isOutdated
84
- ? html`<span class="text-[10px] text-yellow-500/80"
84
+ ? html`<span class="text-[10px] text-status-warning-muted/80"
85
85
  >file changed since scan</span
86
86
  >`
87
- : html`<span class="text-[10px] text-gray-600">snapshot</span>`}
87
+ : html`<span class="text-[10px] text-fg-dim">snapshot</span>`}
88
88
  </div>
89
89
  <div class="relative">
90
90
  <div
91
- class="px-3 py-2 text-[11px] leading-[18px] font-mono text-gray-300 bg-black/20"
91
+ class="px-3 py-2 text-[11px] leading-[18px] font-mono text-body bg-field"
92
92
  style="white-space:pre-wrap;word-break:break-word"
93
93
  >
94
94
  ${visibleLines.map(
95
95
  (line, index) => html`
96
96
  <div class="flex">
97
97
  <span
98
- class="text-gray-600 select-none shrink-0"
98
+ class="text-fg-dim select-none shrink-0"
99
99
  style="width:${gutterWidth +
100
100
  1}ch;text-align:right;margin-right:1ch"
101
101
  >${snippet.startLine + index}</span
@@ -104,7 +104,7 @@ const SnippetBlock = ({ item, onOpenFile, isOutdated }) => {
104
104
  `,
105
105
  )}
106
106
  ${expanded && snippet.truncated
107
- ? html`<div class="text-gray-600 italic pl-1">... truncated</div>`
107
+ ? html`<div class="text-fg-dim italic pl-1">... truncated</div>`
108
108
  : ""}
109
109
  </div>
110
110
  ${isCollapsible && !expanded
@@ -115,7 +115,7 @@ const SnippetBlock = ({ item, onOpenFile, isOutdated }) => {
115
115
  onClick=${() => setExpanded(true)}
116
116
  >
117
117
  <span
118
- class="text-[10px] text-gray-500 hover:text-white flex items-center gap-1 transition-colors"
118
+ class="text-[10px] text-fg-muted hover:text-white flex items-center gap-1 transition-colors"
119
119
  >
120
120
  <span
121
121
  class="inline-block text-xs transition-transform"
@@ -131,10 +131,10 @@ const SnippetBlock = ({ item, onOpenFile, isOutdated }) => {
131
131
  ? html`
132
132
  <button
133
133
  type="button"
134
- class="w-full flex items-center justify-center py-1 cursor-pointer bg-black/20 border-t border-border"
134
+ class="w-full flex items-center justify-center py-1 cursor-pointer bg-field border-t border-border"
135
135
  onClick=${() => setExpanded(false)}
136
136
  >
137
- <span class="text-[10px] text-gray-500 flex items-center gap-1">
137
+ <span class="text-[10px] text-fg-muted flex items-center gap-1">
138
138
  <span
139
139
  class="inline-block transition-transform"
140
140
  aria-hidden="true"
@@ -194,7 +194,7 @@ export const DoctorFindingsList = ({
194
194
  <${Badge} tone=${getDoctorPriorityTone(card.priority)}>
195
195
  ${card.priority}
196
196
  </${Badge}>
197
- <h3 class="text-sm font-semibold text-gray-100">
197
+ <h3 class="text-sm font-semibold text-bright">
198
198
  ${card.title}
199
199
  </h3>
200
200
  </div>
@@ -205,7 +205,7 @@ export const DoctorFindingsList = ({
205
205
  ${
206
206
  showRunMeta
207
207
  ? html`
208
- <span class="text-xs text-gray-600"
208
+ <span class="text-xs text-fg-dim"
209
209
  >Run #${card.runId}</span
210
210
  >
211
211
  `
@@ -217,18 +217,18 @@ export const DoctorFindingsList = ({
217
217
  ${
218
218
  card.summary
219
219
  ? html`<p
220
- class="text-xs text-gray-300 leading-5 pt-1"
220
+ class="text-xs text-body leading-5 pt-1"
221
221
  >
222
222
  ${card.summary}
223
223
  </p>`
224
224
  : null
225
225
  }
226
226
  </div>
227
- <details class="group rounded-lg border border-border bg-black/20">
228
- <summary class="list-none cursor-pointer px-3 py-2.5 text-xs text-gray-400 group-open:border-b group-open:border-border">
227
+ <details class="group rounded-lg border border-border bg-field">
228
+ <summary class="list-none cursor-pointer px-3 py-2.5 text-xs text-fg-muted group-open:border-b group-open:border-border">
229
229
  <span class="inline-flex items-center gap-2">
230
230
  <span
231
- class="inline-block text-gray-500 transition-transform duration-200 group-open:rotate-90"
231
+ class="inline-block text-fg-muted transition-transform duration-200 group-open:rotate-90"
232
232
  aria-hidden="true"
233
233
  >▸</span
234
234
  >
@@ -240,7 +240,7 @@ export const DoctorFindingsList = ({
240
240
  <div class="ac-small-heading">
241
241
  Recommendation
242
242
  </div>
243
- <p class="text-xs text-gray-200 mt-1 leading-5">
243
+ <p class="text-xs text-body mt-1 leading-5">
244
244
  ${card.recommendation}
245
245
  </p>
246
246
  </div>
@@ -265,7 +265,7 @@ export const DoctorFindingsList = ({
265
265
  return html`
266
266
  <button
267
267
  type="button"
268
- class="text-[11px] px-2 py-1 rounded-md bg-black/30 border border-border font-mono text-gray-200 hover:text-white hover:border-gray-500 cursor-pointer transition-colors"
268
+ class="text-[11px] px-2 py-1 rounded-md bg-field border border-border font-mono text-body hover:text-white hover:border-fg-muted cursor-pointer transition-colors"
269
269
  onClick=${(e) => {
270
270
  e.preventDefault();
271
271
  onOpenFile(
@@ -294,7 +294,7 @@ export const DoctorFindingsList = ({
294
294
  <div class="mt-1 space-y-2">
295
295
  ${card.evidence.map(
296
296
  (item) => html`
297
- <div class="text-xs text-gray-400">
297
+ <div class="text-xs text-fg-muted">
298
298
  ${renderEvidenceLine(
299
299
  item,
300
300
  onOpenFile,
@@ -363,7 +363,7 @@ export const DoctorFindingsList = ({
363
363
  ? null
364
364
  : html`
365
365
  <div class="ac-surface-inset rounded-xl p-4 space-y-1.5">
366
- <p class="text-xs text-gray-300 leading-5">
366
+ <p class="text-xs text-body leading-5">
367
367
  No findings currently for this selection.
368
368
  </p>
369
369
  </div>
@@ -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 { sendDoctorCardFix, updateDoctorCardStatus } from "../../lib/api.js";
4
4
  import { showToast } from "../toast.js";
5
5
  import { AgentSendModal } from "../agent-send-modal.js";
@@ -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 { ActionButton } from "../action-button.js";
4
4
  import { getDoctorWarningMessage, shouldShowDoctorWarning } from "./helpers.js";
5
5
 
@@ -14,10 +14,10 @@ export const GeneralDoctorWarning = ({
14
14
  if (!shouldShowDoctorWarning(doctorStatus, dismissedUntilMs)) return null;
15
15
  return html`
16
16
  <div class="bg-yellow-500/10 border border-yellow-500/35 rounded-xl p-4">
17
- <div class="flex flex-col sm:flex-row sm:items-center justify-between gap-3">
17
+ <div class="flex flex-col gap-3">
18
18
  <div class="space-y-1">
19
- <h2 class="font-semibold text-sm text-yellow-300">Drift Doctor</h2>
20
- <p class="text-xs text-yellow-100/80">${getDoctorWarningMessage(doctorStatus)}</p>
19
+ <h2 class="font-semibold text-sm text-status-warning">Drift Doctor</h2>
20
+ <p class="text-xs text-status-warning/80">${getDoctorWarningMessage(doctorStatus)}</p>
21
21
  </div>
22
22
  <div class="flex flex-wrap gap-2">
23
23
  <${ActionButton}
@@ -1,6 +1,6 @@
1
- import { h } from "https://esm.sh/preact";
2
- import { useEffect, useMemo, useState } from "https://esm.sh/preact/hooks";
3
- import htm from "https://esm.sh/htm";
1
+ import { h } from "preact";
2
+ import { useEffect, useMemo, useState } from "preact/hooks";
3
+ import htm from "htm";
4
4
  import { usePolling } from "../../hooks/usePolling.js";
5
5
  import {
6
6
  fetchDoctorCards,
@@ -237,8 +237,8 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
237
237
  [
238
238
  "inline-flex items-center gap-2 rounded-full border px-3 py-1.5 text-xs transition-colors",
239
239
  selected
240
- ? "border-cyan-500/40 bg-cyan-500/10 text-cyan-200 shadow-[0_0_0_1px_rgba(34,211,238,0.08)]"
241
- : "border-border bg-black/20 text-gray-300 hover:border-gray-500 hover:text-gray-100",
240
+ ? "border-cyan-500/40 bg-cyan-500/10 text-status-info shadow-[0_0_0_1px_rgba(34,211,238,0.08)]"
241
+ : "border-border bg-field text-body hover:border-fg-muted hover:text-bright",
242
242
  ].join(" ");
243
243
 
244
244
  const getRunMarkerClassName = (tone = "neutral") => {
@@ -318,7 +318,7 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
318
318
  ${showInitialLoadingState
319
319
  ? html`
320
320
  <div class="bg-surface border border-border rounded-xl p-5">
321
- <div class="flex items-center gap-3 text-sm text-gray-400">
321
+ <div class="flex items-center gap-3 text-sm text-fg-muted">
322
322
  <${LoadingSpinner} className="h-4 w-4" />
323
323
  <span>Loading Drift Doctor...</span>
324
324
  </div>
@@ -335,15 +335,15 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
335
335
  <div
336
336
  class="bg-surface border border-border rounded-xl p-4 flex flex-wrap items-center justify-between gap-3"
337
337
  >
338
- <span class="text-xs text-gray-500">
338
+ <span class="text-xs text-fg-muted">
339
339
  Last run ·${" "}
340
- <span class="text-gray-300">
340
+ <span class="text-body">
341
341
  ${formatLocaleDateTime(doctorStatus?.lastRunAt, {
342
342
  fallback: "Never",
343
343
  })}
344
344
  </span>
345
345
  </span>
346
- <span class="text-xs text-gray-500">
346
+ <span class="text-xs text-fg-muted">
347
347
  ${changeLabel}
348
348
  </span>
349
349
  </div>
@@ -352,7 +352,7 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
352
352
  <div
353
353
  class="bg-surface border border-border rounded-xl p-4 space-y-3"
354
354
  >
355
- <div class="text-xs text-gray-400">
355
+ <div class="text-xs text-fg-muted">
356
356
  ⚠️ ${bootstrapTruncationMessage}
357
357
  </div>
358
358
  <div class="space-y-2">
@@ -363,7 +363,7 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
363
363
  >
364
364
  <button
365
365
  type="button"
366
- class="font-mono text-gray-200 ac-tip-link hover:underline text-left cursor-pointer"
366
+ class="font-mono text-body ac-tip-link hover:underline text-left cursor-pointer"
367
367
  onClick=${() => onOpenFile(String(item.path || ""))}
368
368
  >
369
369
  ${item.path}
@@ -371,13 +371,13 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
371
371
  <span
372
372
  class="flex items-center gap-3 whitespace-nowrap"
373
373
  >
374
- <span class="text-gray-500">
374
+ <span class="text-fg-muted">
375
375
  ${item.size}
376
376
  </span>
377
377
  <span
378
378
  class=${item.statusTone === "warning"
379
- ? "text-yellow-300"
380
- : "text-red-300"}
379
+ ? "text-status-warning"
380
+ : "text-status-error"}
381
381
  >
382
382
  ${item.statusText}
383
383
  </span>
@@ -387,7 +387,7 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
387
387
  )}
388
388
  </div>
389
389
  <div class="border-t border-border"></div>
390
- <p class="text-xs text-gray-500 leading-5">
390
+ <p class="text-xs text-fg-muted leading-5">
391
391
  Truncated files become partially hidden from
392
392
  your agent and could cause drift.
393
393
  </p>
@@ -399,7 +399,7 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
399
399
  ${showDoctorStaleBanner
400
400
  ? html`
401
401
  <div
402
- class="text-xs text-yellow-300 bg-yellow-500/10 border border-yellow-500/35 rounded-lg px-3 py-2"
402
+ class="text-xs text-status-warning bg-yellow-500/10 border border-yellow-500/35 rounded-lg px-3 py-2"
403
403
  >
404
404
  Doctor should be run again because the latest completed
405
405
  run is older than one week and the workspace has
@@ -462,7 +462,7 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
462
462
  ${overflowRuns.length
463
463
  ? html`
464
464
  <label
465
- class="flex items-center gap-2 text-xs text-gray-500"
465
+ class="flex items-center gap-2 text-xs text-fg-muted"
466
466
  >
467
467
  <select
468
468
  value=${selectedOverflowRunValue}
@@ -473,7 +473,7 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
473
473
  if (!nextValue) return;
474
474
  setSelectedRunFilter(nextValue);
475
475
  }}
476
- class="bg-black/20 border border-border rounded-full px-3 py-1.5 text-xs text-gray-300 focus:border-gray-500"
476
+ class="bg-field border border-border rounded-full px-3 py-1.5 text-xs text-body focus:border-fg-muted"
477
477
  >
478
478
  <option value="">More runs</option>
479
479
  ${overflowRuns.map(
@@ -487,14 +487,14 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
487
487
  </label>
488
488
  `
489
489
  : null}
490
- <label class="flex items-center gap-2 text-xs text-gray-500">
490
+ <label class="flex items-center gap-2 text-xs text-fg-muted">
491
491
  <select
492
492
  value=${selectedStatusFilter}
493
493
  onChange=${(event) =>
494
494
  setSelectedStatusFilter(
495
495
  String(event.currentTarget?.value || "open"),
496
496
  )}
497
- class="bg-black/20 border border-border rounded-full px-3 py-1.5 text-xs text-gray-300 focus:border-gray-500"
497
+ class="bg-field border border-border rounded-full px-3 py-1.5 text-xs text-body focus:border-fg-muted"
498
498
  >
499
499
  ${statusFilterOptions.map(
500
500
  (option) => html`
@@ -508,13 +508,13 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
508
508
  ? html`
509
509
  <div class="ac-surface-inset rounded-xl p-4 space-y-1.5">
510
510
  <div
511
- class="text-[11px] uppercase tracking-wide text-gray-500"
511
+ class="text-[11px] uppercase tracking-wide text-fg-muted"
512
512
  >
513
513
  ${selectedRun?.id
514
514
  ? `Run #${selectedRun.id} summary`
515
515
  : "Run summary"}
516
516
  </div>
517
- <p class="text-xs text-gray-300 leading-5">
517
+ <p class="text-xs text-body leading-5">
518
518
  ${selectedRunSummary}
519
519
  </p>
520
520
  </div>
@@ -523,7 +523,7 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
523
523
  ${selectedRunIsInProgress
524
524
  ? html`
525
525
  <div class="ac-surface-inset rounded-xl p-4">
526
- <div class="flex items-center gap-2 text-xs leading-5 text-gray-400">
526
+ <div class="flex items-center gap-2 text-xs leading-5 text-fg-muted">
527
527
  <${LoadingSpinner} className="h-3.5 w-3.5" />
528
528
  <span>
529
529
  Run in progress. Findings will appear when analysis
@@ -557,10 +557,10 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
557
557
  <div class="max-w-md w-full flex flex-col items-center gap-4">
558
558
  <${DoctorEmptyStateIcon} />
559
559
  <div class="space-y-2">
560
- <h2 class="font-semibold text-lg text-gray-100">
560
+ <h2 class="font-semibold text-lg text-bright">
561
561
  Workspace health review
562
562
  </h2>
563
- <p class="text-xs text-gray-400 leading-5">
563
+ <p class="text-xs text-fg-muted leading-5">
564
564
  Drift Doctor scans the workspace for guidance drift,
565
565
  misplaced instructions, redundant docs, and cleanup
566
566
  opportunities.
@@ -576,7 +576,7 @@ export const DoctorTab = ({ isActive = false, onOpenFile = () => {} }) => {
576
576
  loadingLabel="Running..."
577
577
  title=${runDoctorDisabledReason}
578
578
  />
579
- <p class="text-xs text-gray-500 leading-5 mt-10">
579
+ <p class="text-xs text-fg-muted leading-5 mt-10">
580
580
  Runs on your main agent and consumes tokens. No
581
581
  changes will be made without your approval.
582
582
  </p>
@@ -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 { SummaryStatCard } from "../summary-stat-card.js";
4
4
  import { buildDoctorPriorityCounts } from "./helpers.js";
5
5
 
@@ -10,9 +10,9 @@ export const DoctorSummaryCards = ({ cards = [] }) => {
10
10
  return html`
11
11
  <div class="grid grid-cols-1 md:grid-cols-4 gap-3">
12
12
  <${SummaryStatCard} title="Open Findings" value=${cards.length} />
13
- <${SummaryStatCard} title="P0" value=${counts.P0} toneClassName="text-red-400" />
14
- <${SummaryStatCard} title="P1" value=${counts.P1} toneClassName="text-yellow-400" />
15
- <${SummaryStatCard} title="P2" value=${counts.P2} toneClassName="text-gray-300" />
13
+ <${SummaryStatCard} title="P0" value=${counts.P0} toneClassName="text-status-error-muted" />
14
+ <${SummaryStatCard} title="P1" value=${counts.P1} toneClassName="text-status-warning-muted" />
15
+ <${SummaryStatCard} title="P2" value=${counts.P2} toneClassName="text-body" />
16
16
  </div>
17
17
  `;
18
18
  };
@@ -1,11 +1,11 @@
1
- import { h } from "https://esm.sh/preact";
1
+ import { h } from "preact";
2
2
  import {
3
3
  useState,
4
4
  useEffect,
5
5
  useCallback,
6
6
  useRef,
7
- } from "https://esm.sh/preact/hooks";
8
- import htm from "https://esm.sh/htm";
7
+ } from "preact/hooks";
8
+ import htm from "htm";
9
9
  import { fetchEnvVars, saveEnvVars } from "../lib/api.js";
10
10
  import { useCachedFetch } from "../hooks/use-cached-fetch.js";
11
11
  import { showToast } from "./toast.js";
@@ -110,7 +110,7 @@ const kHintByKey = {
110
110
  >console.anthropic.com</a
111
111
  >`,
112
112
  ANTHROPIC_TOKEN: html`from
113
- <code class="text-xs bg-black/30 px-1 rounded">claude setup-token</code>`,
113
+ <code class="text-xs bg-field px-1 rounded">claude setup-token</code>`,
114
114
  OPENAI_API_KEY: html`from${" "}
115
115
  <a
116
116
  href="https://platform.openai.com"
@@ -135,11 +135,11 @@ const kHintByKey = {
135
135
  style="color: var(--accent-link)"
136
136
  >elevenlabs.io</a
137
137
  >${" "} · ${" "}
138
- <code class="text-xs bg-black/30 px-1 rounded">XI_API_KEY</code> also
138
+ <code class="text-xs bg-field px-1 rounded">XI_API_KEY</code> also
139
139
  supported`,
140
140
  GITHUB_WORKSPACE_REPO: html`use
141
- <code class="text-xs bg-black/30 px-1 rounded">owner/repo</code> or
142
- <code class="text-xs bg-black/30 px-1 rounded"
141
+ <code class="text-xs bg-field px-1 rounded">owner/repo</code> or
142
+ <code class="text-xs bg-field px-1 rounded"
143
143
  >https://github.com/owner/repo</code
144
144
  >`,
145
145
  TELEGRAM_BOT_TOKEN: html`from${" "}
@@ -244,7 +244,7 @@ const FeatureIcon = ({ feature }) => {
244
244
  return html`
245
245
  <${Tooltip} text=${label} widthClass="w-auto" tooltipClassName="whitespace-nowrap">
246
246
  <span
247
- class="inline-flex items-center justify-center text-gray-500 hover:text-gray-300 focus-within:text-gray-300"
247
+ class="inline-flex items-center justify-center text-fg-muted hover:text-body focus-within:text-body"
248
248
  tabindex="0"
249
249
  aria-label=${label}
250
250
  >
@@ -287,20 +287,20 @@ const EnvRow = ({ envVar, onChange, onDelete, disabled }) => {
287
287
  onInput=${(e) => onChange(envVar.key, e.target.value)}
288
288
  placeholder=${envVar.value ? "" : "not set"}
289
289
  isSecret=${!!envVar.value}
290
- inputClass="flex-1 min-w-0 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"
290
+ inputClass="flex-1 min-w-0 bg-field border border-border rounded-lg px-3 py-1.5 text-sm text-body outline-none focus:border-fg-muted font-mono"
291
291
  disabled=${disabled}
292
292
  />
293
293
  ${envVar.group === "custom"
294
294
  ? html`<button
295
295
  onclick=${() => onDelete(envVar.key)}
296
- class="text-gray-600 hover:text-red-400 px-1 text-xs shrink-0"
296
+ class="text-fg-dim hover:text-status-error-muted px-1 text-xs shrink-0"
297
297
  title="Delete"
298
298
  >
299
299
 
300
300
  </button>`
301
301
  : null}
302
302
  </div>
303
- ${hint ? html`<p class="text-xs text-gray-600 mt-1">${hint}</p>` : null}
303
+ ${hint ? html`<p class="text-xs text-fg-dim mt-1">${hint}</p>` : null}
304
304
  </div>
305
305
  </div>
306
306
  `;
@@ -590,7 +590,7 @@ export const Envars = ({ onRestartRequired = () => {} }) => {
590
590
  <button
591
591
  type="button"
592
592
  onclick=${() => setShowAllAiKeys((prev) => !prev)}
593
- class="inline-flex items-center gap-1.5 text-xs text-gray-500 hover:text-gray-300"
593
+ class="inline-flex items-center gap-1.5 text-xs text-fg-muted hover:text-body"
594
594
  >
595
595
  <${ChevronDownIcon}
596
596
  className=${`transition-transform ${expanded ? "rotate-180" : ""}`}
@@ -623,7 +623,7 @@ export const Envars = ({ onRestartRequired = () => {} }) => {
623
623
  <${PaneShell}
624
624
  header=${html`<${PageHeader} title="Envars" />`}
625
625
  >
626
- <div class="bg-surface border border-border rounded-xl p-4 text-sm text-gray-500">
626
+ <div class="bg-surface border border-border rounded-xl p-4 text-sm text-fg-muted">
627
627
  Loading environment variables...
628
628
  </div>
629
629
  </${PaneShell}>
@@ -685,7 +685,7 @@ export const Envars = ({ onRestartRequired = () => {} }) => {
685
685
  onInput=${(e) => handleKeyInput(e.target.value)}
686
686
  onPaste=${(e) => handlePaste(e, "key")}
687
687
  onKeyDown=${(e) => e.key === "Enter" && handleAddVar()}
688
- 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 uppercase"
688
+ 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 uppercase"
689
689
  />
690
690
  </div>
691
691
  <div class="flex-1 flex gap-2">
@@ -696,11 +696,11 @@ export const Envars = ({ onRestartRequired = () => {} }) => {
696
696
  onInput=${(e) => handleValInput(e.target.value)}
697
697
  onPaste=${(e) => handlePaste(e, "val")}
698
698
  onKeyDown=${(e) => e.key === "Enter" && handleAddVar()}
699
- class="flex-1 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"
699
+ class="flex-1 bg-field border border-border rounded-lg px-3 py-1.5 text-sm text-body outline-none focus:border-fg-muted font-mono"
700
700
  />
701
701
  <button
702
702
  onclick=${handleAddVar}
703
- class="text-xs px-3 py-1.5 rounded-lg border border-border text-gray-400 hover:text-gray-200 hover:border-gray-500 shrink-0"
703
+ class="text-xs px-3 py-1.5 rounded-lg border border-border text-fg-muted hover:text-body hover:border-fg-muted shrink-0"
704
704
  >
705
705
  + Add
706
706
  </button>
@@ -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 { fetchEnvVars } from "../lib/api.js";
4
4
  import { useCachedFetch } from "../hooks/use-cached-fetch.js";
5
5
  import { Badge } from "./badge.js";
@@ -39,11 +39,11 @@ export const Features = ({ onSwitchTab }) => {
39
39
  const status = resolveFeatureStatus(feature, envVars);
40
40
  return html`
41
41
  <div class="flex justify-between items-center py-1.5">
42
- <span class="text-sm text-gray-300">${feature.label}</span>
42
+ <span class="text-sm text-body">${feature.label}</span>
43
43
  ${status.active
44
44
  ? html`
45
45
  <span class="flex items-center gap-2">
46
- <span class="text-xs text-gray-400">
46
+ <span class="text-xs text-fg-muted">
47
47
  ${kProviderLabels[status.provider] || status.provider}
48
48
  </span>
49
49
  <${Badge} tone="success">Enabled</${Badge}>
@@ -1,12 +1,12 @@
1
- import { h } from "https://esm.sh/preact";
1
+ import { h } from "preact";
2
2
  import {
3
3
  useCallback,
4
4
  useEffect,
5
5
  useMemo,
6
6
  useRef,
7
7
  useState,
8
- } from "https://esm.sh/preact/hooks";
9
- import htm from "https://esm.sh/htm";
8
+ } from "preact/hooks";
9
+ import htm from "htm";
10
10
  import {
11
11
  fetchBrowseTree,
12
12
  deleteBrowseFile,
@@ -1080,7 +1080,7 @@ export const FileTree = ({
1080
1080
  return html`
1081
1081
  <div class="file-tree-wrap file-tree-wrap-loading">
1082
1082
  <div class="file-tree-state file-tree-state-loading">
1083
- <${LoadingSpinner} className="h-5 w-5 text-gray-400" />
1083
+ <${LoadingSpinner} className="h-5 w-5 text-fg-muted" />
1084
1084
  </div>
1085
1085
  </div>
1086
1086
  `;
@@ -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 { LoadingSpinner } from "../loading-spinner.js";
4
4
 
5
5
  const html = htm.bind(h);
@@ -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
 
4
4
  const html = htm.bind(h);
5
5
 
@@ -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 { formatFrontmatterValue } from "../../lib/syntax-highlighters/index.js";
4
4
 
5
5
  const html = htm.bind(h);
@@ -1,6 +1,6 @@
1
- import { h } from "https://esm.sh/preact";
2
- import { useState } from "https://esm.sh/preact/hooks";
3
- import htm from "https://esm.sh/htm";
1
+ import { h } from "preact";
2
+ import { useState } from "preact/hooks";
3
+ import htm from "htm";
4
4
  import { LoadingSpinner } from "../loading-spinner.js";
5
5
  import { ConfirmDialog } from "../confirm-dialog.js";
6
6
  import { SqliteViewer } from "./sqlite-viewer.js";