@chrysb/alphaclaw 0.1.17 → 0.1.19

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.
@@ -48,12 +48,12 @@ body::before {
48
48
  .scope-btn { background: rgba(255,255,255,0.03); color: var(--text-muted); border: 1px solid var(--border); transition: all 0.15s; }
49
49
  .scope-btn:hover { border-color: var(--text-dim); color: var(--text); }
50
50
  .scope-btn-read.active {
51
- background: rgba(255, 255, 255, 0.12);
51
+ background: rgba(255, 255, 255, 0.03);
52
52
  color: #f3f4f6;
53
53
  border-color: rgba(255, 255, 255, 0.35);
54
54
  }
55
55
  .scope-btn-write.active {
56
- background: rgba(255, 255, 255, 0.12);
56
+ background: rgba(255, 255, 255, 0.03);
57
57
  color: #f3f4f6;
58
58
  border-color: rgba(255, 255, 255, 0.35);
59
59
  }
@@ -113,3 +113,37 @@ body::before {
113
113
  color: #a4f3ff;
114
114
  background: rgba(99, 235, 255, 0.08);
115
115
  }
116
+
117
+ .ac-btn-green {
118
+ border: 1px solid rgba(34, 197, 94, 0.45);
119
+ background: linear-gradient(
120
+ 180deg,
121
+ rgba(34, 197, 94, 0.2) 0%,
122
+ rgba(34, 197, 94, 0.12) 100%
123
+ );
124
+ color: #86efac;
125
+ box-shadow: inset 0 0 0 1px rgba(34, 197, 94, 0.12);
126
+ transition:
127
+ border-color 0.15s ease,
128
+ background 0.15s ease,
129
+ color 0.15s ease,
130
+ box-shadow 0.15s ease,
131
+ transform 0.15s ease;
132
+ }
133
+
134
+ .ac-btn-green:hover:not(:disabled) {
135
+ border-color: rgba(34, 197, 94, 0.7);
136
+ background: linear-gradient(
137
+ 180deg,
138
+ rgba(34, 197, 94, 0.28) 0%,
139
+ rgba(34, 197, 94, 0.16) 100%
140
+ );
141
+ color: #bbf7d0;
142
+ box-shadow:
143
+ inset 0 0 0 1px rgba(34, 197, 94, 0.2),
144
+ 0 0 12px rgba(34, 197, 94, 0.12);
145
+ }
146
+
147
+ .ac-btn-green:active:not(:disabled) {
148
+ transform: translateY(1px);
149
+ }
@@ -27,8 +27,11 @@ import { Envars } from "./components/envars.js";
27
27
  import { ToastContainer, showToast } from "./components/toast.js";
28
28
  import { ChevronDownIcon } from "./components/icons.js";
29
29
  const html = htm.bind(h);
30
+ const kUiTabStorageKey = "alphaclaw_ui_tab";
31
+ const kUiTabs = ["general", "models", "envars"];
32
+ const kDefaultUiTab = "general";
30
33
 
31
- const GeneralTab = ({ onSwitchTab }) => {
34
+ const GeneralTab = ({ onSwitchTab, isActive }) => {
32
35
  const [googleKey, setGoogleKey] = useState(0);
33
36
  const [dashboardLoading, setDashboardLoading] = useState(false);
34
37
 
@@ -112,6 +115,11 @@ const GeneralTab = ({ onSwitchTab }) => {
112
115
  setGoogleKey((k) => k + 1);
113
116
  };
114
117
 
118
+ useEffect(() => {
119
+ if (!isActive) return;
120
+ fullRefresh();
121
+ }, [isActive]);
122
+
115
123
  useEffect(() => {
116
124
  if (!syncCron) return;
117
125
  setSyncCronEnabled(syncCron.enabled !== false);
@@ -269,7 +277,14 @@ const GeneralTab = ({ onSwitchTab }) => {
269
277
 
270
278
  function App() {
271
279
  const [onboarded, setOnboarded] = useState(null);
272
- const [tab, setTab] = useState("general");
280
+ const [tab, setTab] = useState(() => {
281
+ try {
282
+ const savedTab = localStorage.getItem(kUiTabStorageKey);
283
+ return kUiTabs.includes(savedTab) ? savedTab : kDefaultUiTab;
284
+ } catch {
285
+ return kDefaultUiTab;
286
+ }
287
+ });
273
288
  const [acVersion, setAcVersion] = useState(null);
274
289
  const [acLatest, setAcLatest] = useState(null);
275
290
  const [acHasUpdate, setAcHasUpdate] = useState(false);
@@ -282,6 +297,12 @@ function App() {
282
297
  .catch(() => setOnboarded(false));
283
298
  }, []);
284
299
 
300
+ useEffect(() => {
301
+ try {
302
+ localStorage.setItem(kUiTabStorageKey, tab);
303
+ } catch {}
304
+ }, [tab]);
305
+
285
306
  useEffect(() => {
286
307
  if (!onboarded) return;
287
308
  let active = true;
@@ -408,7 +429,7 @@ function App() {
408
429
  <div class="app-content">
409
430
  <div class="max-w-2xl w-full mx-auto space-y-4">
410
431
  <div style=${{ display: tab === "general" ? "" : "none" }}>
411
- <${GeneralTab} onSwitchTab=${setTab} />
432
+ <${GeneralTab} onSwitchTab=${setTab} isActive=${tab === "general"} />
412
433
  </div>
413
434
  <div style=${{ display: tab === "models" ? "" : "none" }}>
414
435
  <${Models} />
@@ -55,7 +55,7 @@ const DeviceRow = ({ d, onApprove, onReject }) => {
55
55
  ${subtitle && html`<span class="text-xs text-gray-500">${subtitle}</span>`}
56
56
  </div>
57
57
  <div class="flex gap-2">
58
- <button onclick=${() => handle('approve')} class="bg-green-500 text-black text-xs font-medium px-3 py-1.5 rounded-lg hover:opacity-85">Approve</button>
58
+ <button onclick=${() => handle('approve')} class="ac-btn-green text-xs font-medium px-3 py-1.5 rounded-lg">Approve</button>
59
59
  <button onclick=${() => handle('reject')} class="bg-gray-800 text-gray-300 text-xs px-3 py-1.5 rounded-lg hover:bg-gray-700">Reject</button>
60
60
  </div>
61
61
  </div>`;
@@ -332,11 +332,7 @@ export const Envars = () => {
332
332
  <button
333
333
  onclick=${handleSave}
334
334
  disabled=${!dirty || saving || restartingGateway}
335
- class="w-full text-sm font-medium px-4 py-2.5 rounded-xl transition-all ${dirty &&
336
- !saving &&
337
- !restartingGateway
338
- ? "bg-white text-black hover:opacity-85"
339
- : "bg-gray-800 text-gray-500 cursor-not-allowed"}"
335
+ class="w-full text-sm font-medium px-4 py-2.5 rounded-xl transition-all ac-btn-cyan"
340
336
  >
341
337
  ${saving
342
338
  ? html`<span class="flex items-center justify-center gap-2">
@@ -357,7 +353,7 @@ export const Envars = () => {
357
353
  </svg>
358
354
  Saving...
359
355
  </span>`
360
- : "Save Changes"}
356
+ : "Save changes"}
361
357
  </button>
362
358
  </div>
363
359
  `;
@@ -320,7 +320,7 @@ export const Models = () => {
320
320
  ? html`
321
321
  <button
322
322
  onclick=${startCodexAuth}
323
- class="text-xs font-medium px-3 py-1.5 rounded-lg bg-white text-black hover:opacity-85"
323
+ class="text-xs font-medium px-3 py-1.5 rounded-lg ac-btn-cyan"
324
324
  >
325
325
  Connect Codex OAuth
326
326
  </button>
@@ -357,7 +357,7 @@ export const Models = () => {
357
357
  <button
358
358
  onclick=${completeCodexAuth}
359
359
  disabled=${!codexManualInput.trim() || codexExchanging}
360
- class="text-xs font-medium px-3 py-1.5 rounded-lg ${!codexManualInput.trim() || codexExchanging ? "bg-gray-700 text-gray-400 cursor-not-allowed" : "bg-white text-black hover:opacity-85"}"
360
+ class="text-xs font-medium px-3 py-1.5 rounded-lg ac-btn-cyan"
361
361
  >
362
362
  ${codexExchanging ? "Completing..." : "Complete Codex OAuth"}
363
363
  </button>
@@ -442,9 +442,7 @@ export const Models = () => {
442
442
  <button
443
443
  onclick=${saveChanges}
444
444
  disabled=${!canSaveChanges}
445
- class="w-full text-sm font-medium px-4 py-2.5 rounded-xl transition-all ${canSaveChanges
446
- ? "bg-white text-black hover:opacity-85"
447
- : "bg-gray-800 text-gray-500 cursor-not-allowed"}"
445
+ class="w-full text-sm font-medium px-4 py-2.5 rounded-xl transition-all ac-btn-cyan"
448
446
  >
449
447
  ${savingChanges ? "Saving..." : "Save changes"}
450
448
  </button>
@@ -110,7 +110,7 @@ export const WelcomeFormStep = ({
110
110
  onclick=${startCodexAuth}
111
111
  class="text-xs font-medium px-3 py-1.5 rounded-lg ${codexStatus.connected
112
112
  ? "border border-border text-gray-300 hover:border-gray-500"
113
- : "bg-white text-black hover:opacity-85"}"
113
+ : "ac-btn-cyan"}"
114
114
  >
115
115
  ${codexStatus.connected ? "Reconnect Codex" : "Connect Codex OAuth"}
116
116
  </button>
@@ -148,10 +148,7 @@ export const WelcomeFormStep = ({
148
148
  type="button"
149
149
  onclick=${completeCodexAuth}
150
150
  disabled=${!codexManualInput.trim() || codexExchanging}
151
- class="text-xs font-medium px-3 py-1.5 rounded-lg ${!codexManualInput.trim() ||
152
- codexExchanging
153
- ? "bg-gray-700 text-gray-400 cursor-not-allowed"
154
- : "bg-white text-black hover:opacity-85"}"
151
+ class="text-xs font-medium px-3 py-1.5 rounded-lg ac-btn-cyan"
155
152
  >
156
153
  ${codexExchanging ? "Completing..." : "Complete Codex OAuth"}
157
154
  </button>
@@ -37,7 +37,7 @@ const PairingRow = ({ p, onApprove, onReject }) => {
37
37
  <div class="bg-black/30 rounded-lg p-3 mb-2">
38
38
  <div class="font-medium text-sm mb-2">${label} · <code class="text-gray-400">${p.code || p.id || '?'}</code></div>
39
39
  <div class="flex gap-2">
40
- <button onclick=${() => handle("approve")} class="bg-green-500 text-black text-xs font-medium px-3 py-1.5 rounded-lg hover:opacity-85">Approve</button>
40
+ <button onclick=${() => handle("approve")} class="ac-btn-green text-xs font-medium px-3 py-1.5 rounded-lg">Approve</button>
41
41
  <button onclick=${() => handle("reject")} class="bg-gray-800 text-gray-300 text-xs px-3 py-1.5 rounded-lg hover:bg-gray-700">Reject</button>
42
42
  </div>
43
43
  </div>`;
@@ -224,7 +224,9 @@ export const Welcome = ({ onComplete }) => {
224
224
 
225
225
  try {
226
226
  const vars = Object.entries(vals)
227
- .filter(([key]) => key !== "MODEL_KEY")
227
+ .filter(
228
+ ([key]) => key !== "MODEL_KEY" && !String(key || "").startsWith("_"),
229
+ )
228
230
  .filter(([, v]) => v)
229
231
  .map(([key, value]) => ({ key, value }));
230
232
  const result = await runOnboard(vars, vals.MODEL_KEY);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chrysb/alphaclaw",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },