@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.
- package/lib/public/css/theme.css +36 -2
- package/lib/public/js/app.js +24 -3
- package/lib/public/js/components/device-pairings.js +1 -1
- package/lib/public/js/components/envars.js +2 -6
- package/lib/public/js/components/models.js +3 -5
- package/lib/public/js/components/onboarding/welcome-form-step.js +2 -5
- package/lib/public/js/components/pairings.js +1 -1
- package/lib/public/js/components/welcome.js +3 -1
- package/package.json +1 -1
package/lib/public/css/theme.css
CHANGED
|
@@ -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.
|
|
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.
|
|
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
|
+
}
|
package/lib/public/js/app.js
CHANGED
|
@@ -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(
|
|
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="
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
: "
|
|
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
|
|
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="
|
|
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(
|
|
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);
|