@chrysb/alphaclaw 0.1.4 → 0.1.6
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/js/app.js
CHANGED
|
@@ -278,6 +278,7 @@ function App() {
|
|
|
278
278
|
const data = await updateAlphaclaw();
|
|
279
279
|
if (data.ok) {
|
|
280
280
|
showToast("AlphaClaw updated — restarting...", "success");
|
|
281
|
+
setTimeout(() => window.location.reload(), 5000);
|
|
281
282
|
} else {
|
|
282
283
|
showToast(data.error || "AlphaClaw update failed", "error");
|
|
283
284
|
setAcUpdating(false);
|
|
@@ -15,15 +15,78 @@ const kGroupLabels = {
|
|
|
15
15
|
const kGroupOrder = ["github", "channels", "tools", "custom"];
|
|
16
16
|
|
|
17
17
|
const kHintByKey = {
|
|
18
|
-
ANTHROPIC_API_KEY: html`From
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
ANTHROPIC_API_KEY: html`From{" "}
|
|
19
|
+
<a
|
|
20
|
+
href="https://console.anthropic.com"
|
|
21
|
+
target="_blank"
|
|
22
|
+
class="text-blue-400 hover:underline"
|
|
23
|
+
>console.anthropic.com</a
|
|
24
|
+
>`,
|
|
25
|
+
ANTHROPIC_TOKEN: html`From{" "}
|
|
26
|
+
<code class="text-xs bg-black/30 px-1 rounded">claude setup-token</code>`,
|
|
27
|
+
OPENAI_API_KEY: html`From{" "}
|
|
28
|
+
<a
|
|
29
|
+
href="https://platform.openai.com"
|
|
30
|
+
target="_blank"
|
|
31
|
+
class="text-blue-400 hover:underline"
|
|
32
|
+
>platform.openai.com</a
|
|
33
|
+
>`,
|
|
34
|
+
GEMINI_API_KEY: html`From{" "}
|
|
35
|
+
<a
|
|
36
|
+
href="https://aistudio.google.com"
|
|
37
|
+
target="_blank"
|
|
38
|
+
class="text-blue-400 hover:underline"
|
|
39
|
+
>aistudio.google.com</a
|
|
40
|
+
>`,
|
|
41
|
+
GITHUB_TOKEN: html`Use a <strong>classic PAT</strong> with{" "}
|
|
42
|
+
<code class="text-xs bg-black/30 px-1 rounded">repo</code> scope from
|
|
43
|
+
<a
|
|
44
|
+
href="https://github.com/settings/tokens"
|
|
45
|
+
target="_blank"
|
|
46
|
+
class="text-blue-400 hover:underline"
|
|
47
|
+
>github.com/settings/tokens</a
|
|
48
|
+
>.`,
|
|
49
|
+
GITHUB_WORKSPACE_REPO: html`Use{" "}
|
|
50
|
+
<code class="text-xs bg-black/30 px-1 rounded">owner/repo</code> or
|
|
51
|
+
<code class="text-xs bg-black/30 px-1 rounded"
|
|
52
|
+
>https://github.com/owner/repo</code
|
|
53
|
+
>`,
|
|
54
|
+
TELEGRAM_BOT_TOKEN: html`From{" "}
|
|
55
|
+
<a
|
|
56
|
+
href="https://t.me/BotFather"
|
|
57
|
+
target="_blank"
|
|
58
|
+
class="text-blue-400 hover:underline"
|
|
59
|
+
>@BotFather</a
|
|
60
|
+
>
|
|
61
|
+
·
|
|
62
|
+
<a
|
|
63
|
+
href="https://docs.openclaw.ai/channels/telegram"
|
|
64
|
+
target="_blank"
|
|
65
|
+
class="text-blue-400 hover:underline"
|
|
66
|
+
>full guide</a
|
|
67
|
+
>`,
|
|
68
|
+
DISCORD_BOT_TOKEN: html`From{" "}
|
|
69
|
+
<a
|
|
70
|
+
href="https://discord.com/developers/applications"
|
|
71
|
+
target="_blank"
|
|
72
|
+
class="text-blue-400 hover:underline"
|
|
73
|
+
>Developer Portal</a
|
|
74
|
+
>
|
|
75
|
+
·
|
|
76
|
+
<a
|
|
77
|
+
href="https://docs.openclaw.ai/channels/discord"
|
|
78
|
+
target="_blank"
|
|
79
|
+
class="text-blue-400 hover:underline"
|
|
80
|
+
>full guide</a
|
|
81
|
+
>`,
|
|
82
|
+
BRAVE_API_KEY: html`From{" "}
|
|
83
|
+
<a
|
|
84
|
+
href="https://brave.com/search/api/"
|
|
85
|
+
target="_blank"
|
|
86
|
+
class="text-blue-400 hover:underline"
|
|
87
|
+
>brave.com/search/api</a
|
|
88
|
+
>
|
|
89
|
+
— free tier available`,
|
|
27
90
|
};
|
|
28
91
|
|
|
29
92
|
const getHintContent = (envVar) => kHintByKey[envVar.key] || envVar.hint || "";
|
|
@@ -74,7 +137,9 @@ const EnvRow = ({ envVar, onChange, onDelete, disabled }) => {
|
|
|
74
137
|
: null}
|
|
75
138
|
</div>
|
|
76
139
|
${getHintContent(envVar)
|
|
77
|
-
? html`<p class="text-xs text-gray-600 mt-1"
|
|
140
|
+
? html`<p class="text-xs text-gray-600 mt-1">
|
|
141
|
+
${getHintContent(envVar)}
|
|
142
|
+
</p>`
|
|
78
143
|
: null}
|
|
79
144
|
</div>
|
|
80
145
|
</div>
|
|
@@ -118,7 +183,9 @@ export const Envars = () => {
|
|
|
118
183
|
if (saving) return;
|
|
119
184
|
setSaving(true);
|
|
120
185
|
try {
|
|
121
|
-
const toSave = vars
|
|
186
|
+
const toSave = vars
|
|
187
|
+
.filter((v) => v.editable)
|
|
188
|
+
.map((v) => ({ key: v.key, value: v.value }));
|
|
122
189
|
const result = await saveEnvVars(toSave);
|
|
123
190
|
const needsRestart = !!result?.restartRequired;
|
|
124
191
|
setRestartRequired(needsRestart);
|
|
@@ -153,11 +220,19 @@ export const Envars = () => {
|
|
|
153
220
|
const [newVal, setNewVal] = useState("");
|
|
154
221
|
|
|
155
222
|
const parsePaste = (input) => {
|
|
156
|
-
const lines = input
|
|
223
|
+
const lines = input
|
|
224
|
+
.split("\n")
|
|
225
|
+
.map((l) => l.trim())
|
|
226
|
+
.filter(Boolean)
|
|
227
|
+
.filter((l) => !l.startsWith("#"));
|
|
157
228
|
const pairs = [];
|
|
158
229
|
for (const line of lines) {
|
|
159
230
|
const eqIdx = line.indexOf("=");
|
|
160
|
-
if (eqIdx > 0)
|
|
231
|
+
if (eqIdx > 0)
|
|
232
|
+
pairs.push({
|
|
233
|
+
key: line.slice(0, eqIdx).trim(),
|
|
234
|
+
value: line.slice(eqIdx + 1).trim(),
|
|
235
|
+
});
|
|
161
236
|
}
|
|
162
237
|
return pairs;
|
|
163
238
|
};
|
|
@@ -173,7 +248,15 @@ export const Envars = () => {
|
|
|
173
248
|
if (existing) {
|
|
174
249
|
existing.value = value;
|
|
175
250
|
} else {
|
|
176
|
-
next.push({
|
|
251
|
+
next.push({
|
|
252
|
+
key,
|
|
253
|
+
value,
|
|
254
|
+
label: key,
|
|
255
|
+
group: "custom",
|
|
256
|
+
hint: "",
|
|
257
|
+
source: "env_file",
|
|
258
|
+
editable: true,
|
|
259
|
+
});
|
|
177
260
|
}
|
|
178
261
|
added++;
|
|
179
262
|
}
|
|
@@ -223,7 +306,10 @@ export const Envars = () => {
|
|
|
223
306
|
};
|
|
224
307
|
|
|
225
308
|
const handleAddVar = () => {
|
|
226
|
-
const key = newKey
|
|
309
|
+
const key = newKey
|
|
310
|
+
.trim()
|
|
311
|
+
.toUpperCase()
|
|
312
|
+
.replace(/[^A-Z0-9_]/g, "_");
|
|
227
313
|
if (!key) return;
|
|
228
314
|
addVars([{ key, value: newVal }]);
|
|
229
315
|
setNewKey("");
|
|
@@ -257,16 +343,18 @@ export const Envars = () => {
|
|
|
257
343
|
onChange=${handleChange}
|
|
258
344
|
onDelete=${handleDelete}
|
|
259
345
|
disabled=${saving}
|
|
260
|
-
|
|
346
|
+
/>`,
|
|
261
347
|
)}
|
|
262
348
|
</div>
|
|
263
|
-
|
|
349
|
+
`,
|
|
264
350
|
)}
|
|
265
351
|
|
|
266
352
|
<div class="bg-surface border border-border rounded-xl p-4 space-y-3">
|
|
267
353
|
<div class="flex items-center justify-between">
|
|
268
354
|
<h3 class="text-sm font-medium text-gray-400">Add Variable</h3>
|
|
269
|
-
<span class="text-xs text-gray-600"
|
|
355
|
+
<span class="text-xs text-gray-600"
|
|
356
|
+
>Paste KEY=VALUE or multiple lines</span
|
|
357
|
+
>
|
|
270
358
|
</div>
|
|
271
359
|
<input
|
|
272
360
|
type="text"
|
|
@@ -326,11 +414,7 @@ export const Envars = () => {
|
|
|
326
414
|
>
|
|
327
415
|
${saving
|
|
328
416
|
? html`<span class="flex items-center justify-center gap-2">
|
|
329
|
-
<svg
|
|
330
|
-
class="animate-spin h-4 w-4"
|
|
331
|
-
viewBox="0 0 24 24"
|
|
332
|
-
fill="none"
|
|
333
|
-
>
|
|
417
|
+
<svg class="animate-spin h-4 w-4" viewBox="0 0 24 24" fill="none">
|
|
334
418
|
<circle
|
|
335
419
|
class="opacity-25"
|
|
336
420
|
cx="12"
|
|
@@ -80,7 +80,7 @@ function VersionRow({ label, currentVersion, fetchVersion, applyUpdate, tagsUrl
|
|
|
80
80
|
<div class="flex items-center justify-between gap-3">
|
|
81
81
|
<div class="min-w-0">
|
|
82
82
|
<p class="text-sm text-gray-300 truncate">
|
|
83
|
-
<span class="text-gray-500">${label}</span>${" "}v${version
|
|
83
|
+
<span class="text-gray-500">${label}</span>${" "}${version ? `v${version}` : "..."}
|
|
84
84
|
</p>
|
|
85
85
|
${error && html`<p class="text-xs text-yellow-500 mt-1">${error}</p>`}
|
|
86
86
|
</div>
|
|
@@ -30,19 +30,27 @@ const createAlphaclawVersionService = () => {
|
|
|
30
30
|
|
|
31
31
|
const fetchLatestVersionFromRegistry = () =>
|
|
32
32
|
new Promise((resolve, reject) => {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
resolve(parsed["dist-tags"]?.latest || null);
|
|
41
|
-
} catch (e) {
|
|
42
|
-
reject(new Error("Failed to parse registry response"));
|
|
33
|
+
const doGet = (url, redirects = 0) => {
|
|
34
|
+
if (redirects > 3) return reject(new Error("Too many redirects"));
|
|
35
|
+
const get = url.startsWith("https") ? https.get : http.get;
|
|
36
|
+
get(url, { headers: { Accept: "application/vnd.npm.install-v1+json" } }, (res) => {
|
|
37
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
38
|
+
res.resume();
|
|
39
|
+
return doGet(res.headers.location, redirects + 1);
|
|
43
40
|
}
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
let data = "";
|
|
42
|
+
res.on("data", (chunk) => { data += chunk; });
|
|
43
|
+
res.on("end", () => {
|
|
44
|
+
try {
|
|
45
|
+
const parsed = JSON.parse(data);
|
|
46
|
+
resolve(parsed["dist-tags"]?.latest || null);
|
|
47
|
+
} catch (e) {
|
|
48
|
+
reject(new Error(`Failed to parse registry response (status ${res.statusCode})`));
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}).on("error", reject);
|
|
52
|
+
};
|
|
53
|
+
doGet(kAlphaclawRegistryUrl);
|
|
46
54
|
});
|
|
47
55
|
|
|
48
56
|
const readAlphaclawUpdateStatus = async ({ refresh = false } = {}) => {
|
|
@@ -76,9 +76,6 @@ const createOnboardingService = ({
|
|
|
76
76
|
hasCodexOauth,
|
|
77
77
|
workspaceDir: WORKSPACE_DIR,
|
|
78
78
|
});
|
|
79
|
-
console.log(
|
|
80
|
-
`[onboard] Running: openclaw onboard ${onboardArgs.join(" ").replace(/sk-[^\s]+/g, "***")}`,
|
|
81
|
-
);
|
|
82
79
|
await shellCmd(`openclaw onboard ${onboardArgs.map((a) => `"${a}"`).join(" ")}`, {
|
|
83
80
|
env: {
|
|
84
81
|
...process.env,
|