thepopebot 1.2.76-beta.28 → 1.2.76-beta.30

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 (33) hide show
  1. package/api/index.js +72 -1
  2. package/drizzle/0024_third_moondragon.sql +3 -0
  3. package/drizzle/meta/0024_snapshot.json +771 -0
  4. package/drizzle/meta/_journal.json +7 -0
  5. package/lib/ai/index.js +76 -5
  6. package/lib/auth/actions.js +13 -2
  7. package/lib/chat/actions.js +12 -6
  8. package/lib/chat/api.js +8 -0
  9. package/lib/chat/components/chat-input.js +20 -14
  10. package/lib/chat/components/chat-input.jsx +22 -14
  11. package/lib/chat/components/chat.js +16 -1
  12. package/lib/chat/components/chat.jsx +20 -0
  13. package/lib/chat/components/code-mode-toggle.js +83 -50
  14. package/lib/chat/components/code-mode-toggle.jsx +94 -66
  15. package/lib/chat/components/profile-page.js +99 -7
  16. package/lib/chat/components/profile-page.jsx +115 -19
  17. package/lib/chat/components/settings-coding-agents-page.js +50 -4
  18. package/lib/chat/components/settings-coding-agents-page.jsx +46 -4
  19. package/lib/config.js +4 -0
  20. package/lib/db/schema.js +3 -0
  21. package/lib/db/user-channels.js +9 -0
  22. package/lib/db/users.js +29 -14
  23. package/package.json +2 -1
  24. package/setup/lib/targets.mjs +1 -1
  25. package/templates/skills/CLAUDE.md.template +1 -1
  26. package/templates/skills/agent-job-background/SKILL.md +33 -0
  27. package/templates/skills/agent-job-background/agent-job-background.js +77 -0
  28. package/templates/skills/agent-job-dm/SKILL.md +33 -0
  29. package/templates/skills/agent-job-dm/agent-job-dm.js +69 -0
  30. package/templates/skills/agent-job-secrets/SKILL.md +23 -0
  31. package/templates/skills/agent-job-secrets/agent-job-secrets.js +68 -0
  32. package/templates/skills/agent-job-tools/SKILL.md +0 -44
  33. package/templates/skills/agent-job-tools/agent-job-tools.js +0 -119
package/api/index.js CHANGED
@@ -4,7 +4,8 @@ import { setWebhook } from '../lib/tools/telegram.js';
4
4
  import { getAgentJobStatus, fetchAgentJobLog } from '../lib/tools/github.js';
5
5
  import { getTelegramAdapter } from '../lib/channels/index.js';
6
6
  import { dispatchCommand, dispatchPreAuthCommand } from '../lib/channels/commands/index.js';
7
- import { getByChannelChatId, setActiveThread } from '../lib/db/user-channels.js';
7
+ import { getByChannelChatId, getVerifiedChannels, setActiveThread } from '../lib/db/user-channels.js';
8
+ import { getAllUsers, getUserById } from '../lib/db/users.js';
8
9
  import { chat, chatStream, summarizeAgentJob } from '../lib/ai/index.js';
9
10
  import { createNotification } from '../lib/db/notifications.js';
10
11
  import { getFireTriggers } from '../lib/triggers.js';
@@ -161,6 +162,74 @@ async function handleGetAgentSecret(request) {
161
162
  return Response.json({ value: raw });
162
163
  }
163
164
 
165
+ async function handleListUsers() {
166
+ const users = getAllUsers();
167
+ const enriched = users.map((u) => {
168
+ const channels = getVerifiedChannels(u.id).map((c) => c.channel);
169
+ return {
170
+ id: u.id,
171
+ email: u.email,
172
+ first_name: u.firstName,
173
+ last_name: u.lastName,
174
+ nickname: u.nickname,
175
+ role: u.role,
176
+ channels,
177
+ };
178
+ });
179
+ return Response.json({ users: enriched });
180
+ }
181
+
182
+ async function handleSendDm(request) {
183
+ let body;
184
+ try {
185
+ body = await request.json();
186
+ } catch {
187
+ return Response.json({ error: 'Invalid JSON body' }, { status: 400 });
188
+ }
189
+
190
+ const { user_id, message, channel } = body;
191
+ if (!user_id) return Response.json({ error: 'Missing user_id' }, { status: 400 });
192
+ if (!message || typeof message !== 'string') {
193
+ return Response.json({ error: 'Missing message' }, { status: 400 });
194
+ }
195
+
196
+ const user = getUserById(user_id);
197
+ if (!user) return Response.json({ error: 'User not found' }, { status: 404 });
198
+
199
+ const verified = getVerifiedChannels(user_id);
200
+ if (verified.length === 0) {
201
+ return Response.json({ error: 'User has no verified DM channels' }, { status: 409 });
202
+ }
203
+
204
+ // Pick channel: explicit name, or 'default' / omitted = first verified (Telegram preferred while it's the only impl).
205
+ const wantDefault = !channel || channel === 'default';
206
+ const target = wantDefault
207
+ ? (verified.find((c) => c.channel === 'telegram') || verified[0])
208
+ : verified.find((c) => c.channel === channel);
209
+
210
+ if (!target) {
211
+ return Response.json(
212
+ { error: `User has no verified ${channel} channel`, available: verified.map((c) => c.channel) },
213
+ { status: 409 }
214
+ );
215
+ }
216
+
217
+ if (target.channel === 'telegram') {
218
+ const botToken = getTelegramBotToken();
219
+ if (!botToken) return Response.json({ error: 'Telegram bot token not configured' }, { status: 500 });
220
+ const adapter = getTelegramAdapter(botToken);
221
+ try {
222
+ await adapter.sendResponse(target.channelChatId, message, { chatId: target.channelChatId });
223
+ return Response.json({ ok: true, channel: 'telegram', user_id });
224
+ } catch (err) {
225
+ console.error('Failed to send DM:', err);
226
+ return Response.json({ error: 'Failed to send DM' }, { status: 502 });
227
+ }
228
+ }
229
+
230
+ return Response.json({ error: `Channel "${target.channel}" not implemented` }, { status: 501 });
231
+ }
232
+
164
233
  async function handleListAgentSecrets(request) {
165
234
  const record = verifyApiKey(request.headers.get('x-api-key'));
166
235
  if (record.type !== 'agent_job_api_key') {
@@ -429,6 +498,7 @@ async function POST(request) {
429
498
  // Route to handler
430
499
  switch (routePath) {
431
500
  case '/create-agent-job': return handleCreateAgentJob(request);
501
+ case '/send-dm': return handleSendDm(request);
432
502
  case '/telegram/webhook': return handleTelegramWebhook(request);
433
503
  case '/telegram/register': return handleTelegramRegister(request);
434
504
  case '/github/webhook': return handleGithubWebhook(request);
@@ -449,6 +519,7 @@ async function GET(request) {
449
519
  case '/agent-jobs/status': return handleAgentJobStatus(request);
450
520
  case '/get-agent-job-secret': return handleGetAgentSecret(request);
451
521
  case '/agent-job-list-secrets': return handleListAgentSecrets(request);
522
+ case '/users': return handleListUsers();
452
523
  case '/oauth/callback': return handleOAuthCallback(request);
453
524
  default: return Response.json({ error: 'Not found' }, { status: 404 });
454
525
  }
@@ -0,0 +1,3 @@
1
+ ALTER TABLE `users` ADD `first_name` text;--> statement-breakpoint
2
+ ALTER TABLE `users` ADD `last_name` text;--> statement-breakpoint
3
+ ALTER TABLE `users` ADD `nickname` text;