@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.
- package/bin/alphaclaw.js +18 -0
- package/lib/plugin/usage-tracker/index.js +308 -0
- package/lib/plugin/usage-tracker/openclaw.plugin.json +8 -0
- package/lib/public/css/explorer.css +51 -1
- package/lib/public/css/shell.css +3 -1
- package/lib/public/css/theme.css +35 -0
- package/lib/public/js/app.js +73 -24
- package/lib/public/js/components/file-tree.js +231 -28
- package/lib/public/js/components/file-viewer.js +193 -20
- package/lib/public/js/components/segmented-control.js +33 -0
- package/lib/public/js/components/sidebar.js +14 -32
- package/lib/public/js/components/telegram-workspace/index.js +353 -0
- package/lib/public/js/components/telegram-workspace/manage.js +397 -0
- package/lib/public/js/components/telegram-workspace/onboarding.js +616 -0
- package/lib/public/js/components/usage-tab.js +528 -0
- package/lib/public/js/components/watchdog-tab.js +1 -1
- package/lib/public/js/lib/api.js +25 -1
- package/lib/public/js/lib/telegram-api.js +78 -0
- package/lib/public/js/lib/ui-settings.js +38 -0
- package/lib/public/setup.html +34 -30
- package/lib/server/alphaclaw-version.js +3 -3
- package/lib/server/constants.js +1 -0
- package/lib/server/onboarding/openclaw.js +15 -0
- package/lib/server/routes/auth.js +5 -1
- package/lib/server/routes/telegram.js +185 -60
- package/lib/server/routes/usage.js +133 -0
- package/lib/server/usage-db.js +570 -0
- package/lib/server.js +21 -1
- package/lib/setup/core-prompts/AGENTS.md +0 -101
- package/package.json +1 -1
- 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
|
+
};
|