openclaw-telegram-manager 1.3.0 → 1.3.2

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 (44) hide show
  1. package/dist/lib/include-generator.d.ts +1 -1
  2. package/dist/lib/include-generator.d.ts.map +1 -1
  3. package/dist/lib/include-generator.js +33 -2
  4. package/dist/lib/include-generator.js.map +1 -1
  5. package/dist/plugin.js +29 -2
  6. package/dist/setup.js +33 -15
  7. package/dist/setup.js.map +1 -1
  8. package/package.json +2 -3
  9. package/src/commands/archive.ts +0 -89
  10. package/src/commands/doctor-all.ts +0 -243
  11. package/src/commands/doctor.ts +0 -100
  12. package/src/commands/help.ts +0 -11
  13. package/src/commands/init.ts +0 -376
  14. package/src/commands/list.ts +0 -28
  15. package/src/commands/rename.ts +0 -140
  16. package/src/commands/snooze.ts +0 -69
  17. package/src/commands/status.ts +0 -59
  18. package/src/commands/sync.ts +0 -46
  19. package/src/commands/upgrade.ts +0 -64
  20. package/src/index.ts +0 -91
  21. package/src/lib/audit.ts +0 -44
  22. package/src/lib/auth.ts +0 -96
  23. package/src/lib/capsule.ts +0 -206
  24. package/src/lib/config-restart.ts +0 -167
  25. package/src/lib/doctor-checks.ts +0 -639
  26. package/src/lib/include-generator.ts +0 -174
  27. package/src/lib/registry.ts +0 -197
  28. package/src/lib/security.ts +0 -174
  29. package/src/lib/telegram.ts +0 -311
  30. package/src/lib/types.ts +0 -172
  31. package/src/setup.ts +0 -475
  32. package/src/templates/base/COMMANDS.md +0 -3
  33. package/src/templates/base/CRON.md +0 -3
  34. package/src/templates/base/LINKS.md +0 -3
  35. package/src/templates/base/NOTES.md +0 -3
  36. package/src/templates/base/README.md +0 -3
  37. package/src/templates/base/TODO.md +0 -11
  38. package/src/templates/overlays/coding/ARCHITECTURE.md +0 -3
  39. package/src/templates/overlays/coding/DEPLOY.md +0 -3
  40. package/src/templates/overlays/marketing/CAMPAIGNS.md +0 -3
  41. package/src/templates/overlays/marketing/METRICS.md +0 -3
  42. package/src/templates/overlays/research/FINDINGS.md +0 -3
  43. package/src/templates/overlays/research/SOURCES.md +0 -3
  44. package/src/tool.ts +0 -282
package/src/tool.ts DELETED
@@ -1,282 +0,0 @@
1
- import { readRegistry, withRegistry } from './lib/registry.js';
2
- import { parseAndVerifyCallback, htmlEscape } from './lib/security.js';
3
- import { topicKey } from './lib/types.js';
4
- import { appendAudit, buildAuditEntry } from './lib/audit.js';
5
- import { handleInitInteractive, handleInitSlugConfirm, handleInitTypeSelect } from './commands/init.js';
6
- import { handleDoctor } from './commands/doctor.js';
7
- import { handleDoctorAll } from './commands/doctor-all.js';
8
- import { handleList } from './commands/list.js';
9
- import { handleStatus } from './commands/status.js';
10
- import { handleSync } from './commands/sync.js';
11
- import { handleRename } from './commands/rename.js';
12
- import { handleUpgrade } from './commands/upgrade.js';
13
- import { handleSnooze } from './commands/snooze.js';
14
- import { handleArchive, handleUnarchive } from './commands/archive.js';
15
- import { handleHelp } from './commands/help.js';
16
- import type { CommandContext, CommandResult } from './commands/help.js';
17
- import type { Logger, RpcInterface } from './lib/config-restart.js';
18
-
19
- // ── Dependencies ──────────────────────────────────────────────────────
20
-
21
- export interface ToolDeps {
22
- logger: Logger;
23
- configDir: string;
24
- workspaceDir: string;
25
- rpc?: RpcInterface | null;
26
- }
27
-
28
- // ── Tool instance ─────────────────────────────────────────────────────
29
-
30
- export interface TopicManagerTool {
31
- execute(
32
- _id: string,
33
- params: { command: string },
34
- execContext?: Record<string, unknown>,
35
- ): Promise<CommandResult>;
36
- }
37
-
38
- // ── Factory ───────────────────────────────────────────────────────────
39
-
40
- export function createTopicManagerTool(deps: ToolDeps): TopicManagerTool {
41
- const { logger, configDir, workspaceDir, rpc } = deps;
42
-
43
- return {
44
- async execute(
45
- _id: string,
46
- params: { command: string },
47
- execContext?: Record<string, unknown>,
48
- ): Promise<CommandResult> {
49
- const commandStr = (params.command ?? '').trim();
50
-
51
- if (!commandStr) {
52
- return { text: 'No command provided. Try /topic help for available commands.' };
53
- }
54
-
55
- // Extract context from execution params
56
- const ctx = buildContext(deps, execContext);
57
-
58
- // Handle tm: callback routing
59
- if (commandStr.startsWith('tm:')) {
60
- return handleCallback(commandStr, ctx);
61
- }
62
-
63
- // Parse sub-command and args
64
- const { subCommand, args, flags } = parseCommand(commandStr);
65
-
66
- try {
67
- switch (subCommand) {
68
- case 'init':
69
- return await handleInitInteractive(ctx, args);
70
-
71
- case 'doctor':
72
- if (flags.has('--all') || flags.has('all')) {
73
- return await handleDoctorAll(ctx);
74
- }
75
- return await handleDoctor(ctx);
76
-
77
- case 'doctor-all':
78
- return await handleDoctorAll(ctx);
79
-
80
- case 'list':
81
- return await handleList(ctx);
82
-
83
- case 'status':
84
- return await handleStatus(ctx);
85
-
86
- case 'sync':
87
- return await handleSync(ctx);
88
-
89
- case 'rename':
90
- return await handleRename(ctx, args);
91
-
92
- case 'upgrade':
93
- return await handleUpgrade(ctx);
94
-
95
- case 'snooze':
96
- return await handleSnooze(ctx, args);
97
-
98
- case 'archive':
99
- return await handleArchive(ctx);
100
-
101
- case 'unarchive':
102
- return await handleUnarchive(ctx);
103
-
104
- case 'help':
105
- return await handleHelp(ctx);
106
-
107
- default:
108
- return {
109
- text: `Unknown command: "${htmlEscape(subCommand)}". Try /topic help for available commands.`,
110
- };
111
- }
112
- } catch (err) {
113
- const msg = err instanceof Error ? err.message : String(err);
114
- logger.error(`[topic_manager] Command "${subCommand}" failed: ${msg}`);
115
- return {
116
- text: `Command failed: ${htmlEscape(msg)}`,
117
- };
118
- }
119
- },
120
- };
121
- }
122
-
123
- // ── Command parsing ───────────────────────────────────────────────────
124
-
125
- interface ParsedCommand {
126
- subCommand: string;
127
- args: string;
128
- flags: Set<string>;
129
- }
130
-
131
- function parseCommand(commandStr: string): ParsedCommand {
132
- const parts = commandStr.split(/\s+/);
133
- const subCommand = (parts[0] ?? '').toLowerCase();
134
- const remaining = parts.slice(1);
135
-
136
- const flags = new Set<string>();
137
- const argParts: string[] = [];
138
-
139
- for (const part of remaining) {
140
- if (part.startsWith('--')) {
141
- flags.add(part);
142
- } else {
143
- argParts.push(part);
144
- }
145
- }
146
-
147
- return {
148
- subCommand,
149
- args: argParts.join(' '),
150
- flags,
151
- };
152
- }
153
-
154
- // ── Context building ────────────────────────────────────────────────
155
-
156
- function buildContext(deps: ToolDeps, execContext?: Record<string, unknown>): CommandContext {
157
- // Extract IDs from the execution context provided by the tool framework
158
- const groupId = extractString(execContext, 'groupId')
159
- ?? extractString(execContext, 'chatId')
160
- ?? extractNestedString(execContext, 'message', 'chat', 'id');
161
-
162
- const threadId = extractString(execContext, 'threadId')
163
- ?? extractString(execContext, 'messageThreadId')
164
- ?? extractNestedString(execContext, 'message', 'message_thread_id');
165
-
166
- const userId = extractString(execContext, 'userId')
167
- ?? extractNestedString(execContext, 'message', 'from', 'id');
168
-
169
- return {
170
- workspaceDir: deps.workspaceDir,
171
- configDir: deps.configDir,
172
- rpc: deps.rpc,
173
- logger: deps.logger,
174
- groupId: groupId ?? undefined,
175
- threadId: threadId ?? undefined,
176
- userId: userId ?? undefined,
177
- messageContext: execContext,
178
- };
179
- }
180
-
181
- function extractString(obj: Record<string, unknown> | undefined, key: string): string | null {
182
- if (!obj) return null;
183
- const val = obj[key];
184
- if (val === undefined || val === null) return null;
185
- return String(val);
186
- }
187
-
188
- function extractNestedString(
189
- obj: Record<string, unknown> | undefined,
190
- ...keys: string[]
191
- ): string | null {
192
- if (!obj) return null;
193
- let current: unknown = obj;
194
- for (const key of keys) {
195
- if (current === null || current === undefined || typeof current !== 'object') return null;
196
- current = (current as Record<string, unknown>)[key];
197
- }
198
- if (current === undefined || current === null) return null;
199
- return String(current);
200
- }
201
-
202
- // ── Callback handling ───────────────────────────────────────────────
203
-
204
- async function handleCallback(data: string, ctx: CommandContext): Promise<CommandResult> {
205
- const { workspaceDir, groupId, threadId, userId } = ctx;
206
-
207
- if (!groupId || !threadId || !userId) {
208
- return { text: 'Cannot verify callback: missing context.' };
209
- }
210
-
211
- const registry = readRegistry(workspaceDir);
212
- const parsed = parseAndVerifyCallback(data, registry.callbackSecret, groupId, threadId);
213
-
214
- if (!parsed) {
215
- return { text: 'Invalid or expired callback.' };
216
- }
217
-
218
- const { action, slug } = parsed;
219
-
220
- // Init callbacks: topic doesn't exist in registry yet
221
- const initTypeMap: Record<string, 'coding' | 'research' | 'marketing' | 'custom'> = {
222
- ic: 'coding',
223
- ir: 'research',
224
- im: 'marketing',
225
- ix: 'custom',
226
- };
227
-
228
- if (action === 'is') {
229
- return handleInitSlugConfirm(ctx, slug);
230
- }
231
- if (action in initTypeMap) {
232
- return handleInitTypeSelect(ctx, slug, initTypeMap[action]!);
233
- }
234
-
235
- // Find the topic entry by slug
236
- const key = topicKey(groupId, threadId);
237
- const entry = registry.topics[key];
238
-
239
- if (!entry || entry.slug !== slug) {
240
- return { text: 'Topic not found or slug mismatch.' };
241
- }
242
-
243
- switch (action) {
244
- case 'fix':
245
- return handleCallbackFix(ctx);
246
-
247
- case 'snooze7d':
248
- return handleSnooze(ctx, '7d');
249
-
250
- case 'snooze30d':
251
- return handleSnooze(ctx, '30d');
252
-
253
- case 'archive':
254
- return handleArchive(ctx);
255
-
256
- case 'ignore': {
257
- // Add the most recent failing check to ignoreChecks
258
- // For simplicity, we acknowledge the action; the user should specify which check
259
- return {
260
- text: `To ignore a specific check, use: /topic snooze or contact an admin. The "Ignore" action requires specifying a check ID.`,
261
- };
262
- }
263
-
264
- default:
265
- return { text: `Unknown callback action: ${htmlEscape(action)}` };
266
- }
267
- }
268
-
269
- async function handleCallbackFix(ctx: CommandContext): Promise<CommandResult> {
270
- // "Fix" re-runs doctor, which auto-fixes fixable issues
271
- // For now, doctor itself identifies fixable issues
272
- const { userId, workspaceDir } = ctx;
273
-
274
- if (userId) {
275
- appendAudit(
276
- workspaceDir,
277
- buildAuditEntry(userId, 'doctor fix', 'callback', 'Fix callback triggered'),
278
- );
279
- }
280
-
281
- return handleDoctor(ctx);
282
- }