@chrysb/alphaclaw 0.3.3 → 0.3.4

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 (31) hide show
  1. package/bin/alphaclaw.js +18 -0
  2. package/lib/plugin/usage-tracker/index.js +308 -0
  3. package/lib/plugin/usage-tracker/openclaw.plugin.json +8 -0
  4. package/lib/public/css/explorer.css +51 -1
  5. package/lib/public/css/shell.css +3 -1
  6. package/lib/public/css/theme.css +35 -0
  7. package/lib/public/js/app.js +73 -24
  8. package/lib/public/js/components/file-tree.js +231 -28
  9. package/lib/public/js/components/file-viewer.js +193 -20
  10. package/lib/public/js/components/segmented-control.js +33 -0
  11. package/lib/public/js/components/sidebar.js +14 -32
  12. package/lib/public/js/components/telegram-workspace/index.js +353 -0
  13. package/lib/public/js/components/telegram-workspace/manage.js +397 -0
  14. package/lib/public/js/components/telegram-workspace/onboarding.js +616 -0
  15. package/lib/public/js/components/usage-tab.js +528 -0
  16. package/lib/public/js/components/watchdog-tab.js +1 -1
  17. package/lib/public/js/lib/api.js +25 -1
  18. package/lib/public/js/lib/telegram-api.js +78 -0
  19. package/lib/public/js/lib/ui-settings.js +38 -0
  20. package/lib/public/setup.html +34 -30
  21. package/lib/server/alphaclaw-version.js +3 -3
  22. package/lib/server/constants.js +1 -0
  23. package/lib/server/onboarding/openclaw.js +15 -0
  24. package/lib/server/routes/auth.js +5 -1
  25. package/lib/server/routes/telegram.js +185 -60
  26. package/lib/server/routes/usage.js +133 -0
  27. package/lib/server/usage-db.js +570 -0
  28. package/lib/server.js +21 -1
  29. package/lib/setup/core-prompts/AGENTS.md +0 -101
  30. package/package.json +1 -1
  31. package/lib/public/js/components/telegram-workspace.js +0 -1365
@@ -0,0 +1,353 @@
1
+ import { h } from "https://esm.sh/preact";
2
+ import { useState, useEffect } from "https://esm.sh/preact/hooks";
3
+ import htm from "https://esm.sh/htm";
4
+ import { showToast } from "../toast.js";
5
+ import * as api from "../../lib/telegram-api.js";
6
+ import {
7
+ StepIndicator,
8
+ VerifyBotStep,
9
+ CreateGroupStep,
10
+ AddBotStep,
11
+ TopicsStep,
12
+ SummaryStep,
13
+ } from "./onboarding.js";
14
+ import { ManageTelegramWorkspace } from "./manage.js";
15
+
16
+ const html = htm.bind(h);
17
+
18
+ const kSteps = [
19
+ { id: "verify-bot", label: "Verify Bot" },
20
+ { id: "create-group", label: "Create Group" },
21
+ { id: "add-bot", label: "Add Bot" },
22
+ { id: "topics", label: "Topics" },
23
+ { id: "summary", label: "Summary" },
24
+ ];
25
+
26
+ const kTelegramWorkspaceStorageKey = "telegram-workspace-state-v1";
27
+ const kTelegramWorkspaceCacheKey = "telegram-workspace-cache-v1";
28
+ const loadTelegramWorkspaceState = () => {
29
+ try {
30
+ const raw = window.localStorage.getItem(kTelegramWorkspaceStorageKey);
31
+ if (!raw) return {};
32
+ const parsed = JSON.parse(raw);
33
+ return parsed && typeof parsed === "object" ? parsed : {};
34
+ } catch {
35
+ return {};
36
+ }
37
+ };
38
+ const loadTelegramWorkspaceCache = () => {
39
+ try {
40
+ const raw = window.localStorage.getItem(kTelegramWorkspaceCacheKey);
41
+ if (!raw) return null;
42
+ const parsed = JSON.parse(raw);
43
+ const data = parsed?.data;
44
+ if (!data || typeof data !== "object") return null;
45
+ return data;
46
+ } catch {
47
+ return null;
48
+ }
49
+ };
50
+ const saveTelegramWorkspaceCache = (data) => {
51
+ try {
52
+ window.localStorage.setItem(
53
+ kTelegramWorkspaceCacheKey,
54
+ JSON.stringify({ cachedAt: Date.now(), data }),
55
+ );
56
+ } catch {}
57
+ };
58
+
59
+ const BackButton = ({ onBack }) => html`
60
+ <button
61
+ onclick=${onBack}
62
+ class="flex items-center gap-1.5 text-sm text-gray-500 hover:text-gray-300 transition-colors mb-4"
63
+ >
64
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
65
+ <path
66
+ d="M10.354 3.354a.5.5 0 00-.708-.708l-5 5a.5.5 0 000 .708l5 5a.5.5 0 00.708-.708L5.707 8l4.647-4.646z"
67
+ />
68
+ </svg>
69
+ Back
70
+ </button>
71
+ `;
72
+
73
+ export const TelegramWorkspace = ({ onBack }) => {
74
+ const initialState = loadTelegramWorkspaceState();
75
+ const cachedWorkspace = loadTelegramWorkspaceCache();
76
+ const [step, setStep] = useState(() => {
77
+ const value = Number.parseInt(String(initialState.step ?? 0), 10);
78
+ if (!Number.isFinite(value)) return 0;
79
+ return Math.min(Math.max(value, 0), kSteps.length - 1);
80
+ });
81
+ const [botInfo, setBotInfo] = useState(initialState.botInfo || null);
82
+ const [groupId, setGroupId] = useState(initialState.groupId || "");
83
+ const [groupInfo, setGroupInfo] = useState(initialState.groupInfo || null);
84
+ const [verifyGroupError, setVerifyGroupError] = useState(
85
+ initialState.verifyGroupError || null,
86
+ );
87
+ const [allowUserId, setAllowUserId] = useState(
88
+ initialState.allowUserId || "",
89
+ );
90
+ const [topics, setTopics] = useState(initialState.topics || {});
91
+ const [workspaceConfig, setWorkspaceConfig] = useState(() => ({
92
+ ready: !!cachedWorkspace,
93
+ configured: !!cachedWorkspace?.configured,
94
+ groupId: cachedWorkspace?.groupId || "",
95
+ groupName: cachedWorkspace?.groupName || "",
96
+ topics: cachedWorkspace?.topics || {},
97
+ debugEnabled: !!cachedWorkspace?.debugEnabled,
98
+ concurrency: cachedWorkspace?.concurrency || {
99
+ agentMaxConcurrent: null,
100
+ subagentMaxConcurrent: null,
101
+ },
102
+ }));
103
+
104
+ const goNext = () => setStep((s) => Math.min(kSteps.length - 1, s + 1));
105
+ const goBack = () => setStep((s) => Math.max(0, s - 1));
106
+ const resetOnboarding = async () => {
107
+ try {
108
+ const data = await api.resetWorkspace();
109
+ if (!data.ok) throw new Error(data.error || "Failed to reset onboarding");
110
+ try {
111
+ window.localStorage.removeItem(kTelegramWorkspaceStorageKey);
112
+ window.localStorage.removeItem(kTelegramWorkspaceCacheKey);
113
+ } catch {}
114
+ setStep(0);
115
+ setBotInfo(null);
116
+ setGroupId("");
117
+ setGroupInfo(null);
118
+ setVerifyGroupError(null);
119
+ setAllowUserId("");
120
+ setTopics({});
121
+ setWorkspaceConfig({
122
+ ready: true,
123
+ configured: false,
124
+ groupId: "",
125
+ groupName: "",
126
+ topics: {},
127
+ debugEnabled: !!workspaceConfig?.debugEnabled,
128
+ concurrency: { agentMaxConcurrent: null, subagentMaxConcurrent: null },
129
+ });
130
+ showToast("Telegram onboarding reset", "success");
131
+ } catch (e) {
132
+ showToast(e.message || "Failed to reset onboarding", "error");
133
+ }
134
+ };
135
+ const handleDone = () => {
136
+ try {
137
+ window.localStorage.removeItem(kTelegramWorkspaceStorageKey);
138
+ window.localStorage.setItem(
139
+ kTelegramWorkspaceCacheKey,
140
+ JSON.stringify({
141
+ cachedAt: Date.now(),
142
+ data: {
143
+ ready: true,
144
+ configured: true,
145
+ groupId,
146
+ groupName: groupInfo?.chat?.title || groupId,
147
+ topics: topics || {},
148
+ debugEnabled: !!workspaceConfig?.debugEnabled,
149
+ concurrency: workspaceConfig?.concurrency || {
150
+ agentMaxConcurrent: null,
151
+ subagentMaxConcurrent: null,
152
+ },
153
+ },
154
+ }),
155
+ );
156
+ } catch {}
157
+ window.location.reload();
158
+ };
159
+
160
+ useEffect(() => {
161
+ try {
162
+ window.localStorage.setItem(
163
+ kTelegramWorkspaceStorageKey,
164
+ JSON.stringify({
165
+ step,
166
+ botInfo,
167
+ groupId,
168
+ groupInfo,
169
+ verifyGroupError,
170
+ allowUserId,
171
+ topics,
172
+ }),
173
+ );
174
+ } catch {}
175
+ }, [
176
+ step,
177
+ botInfo,
178
+ groupId,
179
+ groupInfo,
180
+ verifyGroupError,
181
+ allowUserId,
182
+ topics,
183
+ ]);
184
+
185
+ useEffect(() => {
186
+ let active = true;
187
+ const bootstrapWorkspace = async () => {
188
+ try {
189
+ const data = await api.workspace();
190
+ if (!active || !data?.ok) return;
191
+ if (!data.configured || !data.groupId) {
192
+ const nextConfig = {
193
+ ready: true,
194
+ configured: false,
195
+ groupId: "",
196
+ groupName: "",
197
+ topics: {},
198
+ debugEnabled: !!data?.debugEnabled,
199
+ concurrency: {
200
+ agentMaxConcurrent: null,
201
+ subagentMaxConcurrent: null,
202
+ },
203
+ };
204
+ setWorkspaceConfig(nextConfig);
205
+ saveTelegramWorkspaceCache(nextConfig);
206
+ return;
207
+ }
208
+ const nextConfig = {
209
+ ready: true,
210
+ configured: true,
211
+ groupId: data.groupId,
212
+ groupName: data.groupName || data.groupId,
213
+ topics: data.topics || {},
214
+ debugEnabled: !!data.debugEnabled,
215
+ concurrency: data.concurrency || {
216
+ agentMaxConcurrent: null,
217
+ subagentMaxConcurrent: null,
218
+ },
219
+ };
220
+ setWorkspaceConfig(nextConfig);
221
+ saveTelegramWorkspaceCache(nextConfig);
222
+ setGroupId(data.groupId);
223
+ setTopics(data.topics || {});
224
+ setGroupInfo({
225
+ chat: {
226
+ id: data.groupId,
227
+ title: data.groupName || data.groupId,
228
+ isForum: true,
229
+ },
230
+ bot: {
231
+ status: "administrator",
232
+ isAdmin: true,
233
+ canManageTopics: true,
234
+ },
235
+ });
236
+ setVerifyGroupError(null);
237
+ setAllowUserId("");
238
+ setStep((currentStep) => (currentStep < 3 ? 3 : currentStep));
239
+ } catch {}
240
+ };
241
+ bootstrapWorkspace();
242
+ return () => {
243
+ active = false;
244
+ };
245
+ }, []);
246
+
247
+ return html`
248
+ <div class="space-y-4">
249
+ <${BackButton} onBack=${onBack} />
250
+ <div class="bg-surface border border-border rounded-xl p-4">
251
+ ${!workspaceConfig.ready
252
+ ? html`
253
+ <div class="min-h-[220px] flex items-center justify-center">
254
+ <p class="text-sm text-gray-500">Loading workspace...</p>
255
+ </div>
256
+ `
257
+ : workspaceConfig.configured
258
+ ? html`
259
+ <div class="flex items-center justify-between mb-4">
260
+ <div class="flex items-center gap-2">
261
+ <img
262
+ src="/assets/icons/telegram.svg"
263
+ alt=""
264
+ class="w-5 h-5"
265
+ />
266
+ <h2 class="font-semibold text-sm">
267
+ Manage Telegram Workspace
268
+ </h2>
269
+ </div>
270
+ </div>
271
+ <${ManageTelegramWorkspace}
272
+ groupId=${workspaceConfig.groupId}
273
+ groupName=${workspaceConfig.groupName}
274
+ initialTopics=${workspaceConfig.topics}
275
+ configAgentMaxConcurrent=${workspaceConfig.concurrency
276
+ ?.agentMaxConcurrent}
277
+ configSubagentMaxConcurrent=${workspaceConfig.concurrency
278
+ ?.subagentMaxConcurrent}
279
+ debugEnabled=${workspaceConfig.debugEnabled}
280
+ onResetOnboarding=${resetOnboarding}
281
+ />
282
+ `
283
+ : html`
284
+ <div class="flex items-center justify-between mb-4">
285
+ <div class="flex items-center gap-2">
286
+ <img
287
+ src="/assets/icons/telegram.svg"
288
+ alt=""
289
+ class="w-5 h-5"
290
+ />
291
+ <h2 class="font-semibold text-sm">
292
+ Set Up Telegram Workspace
293
+ </h2>
294
+ </div>
295
+ <span class="text-xs text-gray-500"
296
+ >Step ${step + 1} of ${kSteps.length}</span
297
+ >
298
+ </div>
299
+
300
+ <${StepIndicator} currentStep=${step} steps=${kSteps} />
301
+
302
+ ${step === 0 &&
303
+ html`
304
+ <${VerifyBotStep}
305
+ botInfo=${botInfo}
306
+ setBotInfo=${setBotInfo}
307
+ onNext=${goNext}
308
+ />
309
+ `}
310
+ ${step === 1 &&
311
+ html`
312
+ <${CreateGroupStep} onNext=${goNext} onBack=${goBack} />
313
+ `}
314
+ ${step === 2 &&
315
+ html`
316
+ <${AddBotStep}
317
+ groupId=${groupId}
318
+ setGroupId=${setGroupId}
319
+ groupInfo=${groupInfo}
320
+ setGroupInfo=${setGroupInfo}
321
+ userId=${allowUserId}
322
+ setUserId=${setAllowUserId}
323
+ verifyGroupError=${verifyGroupError}
324
+ setVerifyGroupError=${setVerifyGroupError}
325
+ onNext=${goNext}
326
+ onBack=${goBack}
327
+ />
328
+ `}
329
+ ${step === 3 &&
330
+ html`
331
+ <${TopicsStep}
332
+ groupId=${groupId}
333
+ topics=${topics}
334
+ setTopics=${setTopics}
335
+ onNext=${goNext}
336
+ onBack=${goBack}
337
+ />
338
+ `}
339
+ ${step === 4 &&
340
+ html`
341
+ <${SummaryStep}
342
+ groupId=${groupId}
343
+ groupInfo=${groupInfo}
344
+ topics=${topics}
345
+ onBack=${goBack}
346
+ onDone=${handleDone}
347
+ />
348
+ `}
349
+ `}
350
+ </div>
351
+ </div>
352
+ `;
353
+ };