thepopebot 1.2.78-beta.1 → 1.2.78

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/README.md CHANGED
@@ -95,6 +95,10 @@ the agent already knows what you were just talking about.
95
95
 
96
96
  ## Install
97
97
 
98
+ Prefer to follow along on video? 👇
99
+
100
+ > ### 📺 <a href="https://youtu.be/xmxEEAXFtm8" target="_blank" rel="noopener"><strong>Install Video (click here)</strong></a>
101
+
98
102
  ### Prerequisites
99
103
 
100
104
  | Requirement | Install |
@@ -109,14 +113,31 @@ the agent already knows what you were just talking about.
109
113
 
110
114
  ### Two steps
111
115
 
116
+ **1. Scaffold the project.**
117
+
112
118
  ```bash
113
119
  mkdir my-agent && cd my-agent
114
- npx thepopebot@latest init # scaffold project
115
- npm run setup # interactive wizard
120
+ npx thepopebot@latest init
121
+ ```
122
+
123
+ **2. Run the interactive setup wizard.**
124
+
125
+ ```bash
126
+ npm run setup
116
127
  ```
117
128
 
118
129
  The wizard checks prerequisites, creates a GitHub repo, generates a PAT, configures your URL, and starts Docker. Visit your APP_URL when it finishes.
119
130
 
131
+ ### After setup
132
+
133
+ Sign in at your APP_URL and configure these three, in order, before you can chat or run agent jobs:
134
+
135
+ 1. **Providers** — `/admin/event-handler/llms`. Add API keys for the LLM providers you want to use (Anthropic, OpenAI, Google, etc.). Everything else pulls from these credentials.
136
+ 2. **Helper LLM** — `/admin/event-handler/helper-llm`. Pick provider + model for one-shot calls (chat titles, agent-job titles, PR-merge summaries). Only providers with keys from step 1 appear here.
137
+ 3. **Coding agent** — `/admin/event-handler/coding-agents`. Pick which agent (Claude Code, Pi, Codex, Gemini, OpenCode, Kimi) drives live chat, code workspaces, and background agent jobs, and configure its model.
138
+
139
+ Optional: connect Telegram at `/admin/event-handler/telegram` to talk to your bot from your phone.
140
+
120
141
  > **Local installs**: your server needs to be reachable from the internet for GitHub webhooks and Telegram. Use [ngrok](https://ngrok.com) (`ngrok http 80`). If your ngrok URL changes, run `npx thepopebot set-var APP_URL <new-url>` and re-register the Telegram webhook from `/admin/event-handler/telegram`.
121
142
 
122
143
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thepopebot",
3
- "version": "1.2.78-beta.1",
3
+ "version": "1.2.78",
4
4
  "type": "module",
5
5
  "description": "Create autonomous AI agents with a two-layer architecture: Next.js Event Handler + Docker Agent.",
6
6
  "bin": {
package/setup/setup.mjs CHANGED
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { execSync } from 'child_process';
4
- import http from 'http';
5
4
  import fs from 'fs';
6
5
  import path from 'path';
7
6
  import chalk from 'chalk';
@@ -436,86 +435,15 @@ async function main() {
436
435
  // ─── Step 5: Start Server ─────────────────────────────────────────────
437
436
  clack.log.step(`[${++currentStep}/${TOTAL_STEPS}] Start Server`);
438
437
 
439
- // Probe /login (not /api/ping) to confirm Next.js can actually render
440
- // the page, not just answer API routes. /login serves SetupForm on a
441
- // fresh install; LoginForm once a user exists. Either way it's HTML.
442
- // Traefik routes by Host(`${APP_HOSTNAME}`), so a bare localhost:80
443
- // request hits Traefik's default 404 — set the Host header to match.
444
- // node:http is used (not fetch) because undici silently strips Host.
445
- const appHostname = collected.APP_HOSTNAME;
446
- function isLoginPageReady(timeoutMs = 2000) {
447
- return new Promise((resolve) => {
448
- const req = http.request(
449
- {
450
- host: '127.0.0.1',
451
- port: 80,
452
- method: 'GET',
453
- path: '/login',
454
- headers: { Host: appHostname },
455
- timeout: timeoutMs,
456
- },
457
- (res) => {
458
- const ok = res.statusCode === 200 && (res.headers['content-type'] || '').includes('text/html');
459
- res.resume();
460
- resolve(ok);
461
- }
462
- );
463
- req.on('error', () => resolve(false));
464
- req.on('timeout', () => { req.destroy(); resolve(false); });
465
- req.end();
466
- });
467
- }
468
-
469
- let serverUp = await isLoginPageReady(3000);
470
-
471
- if (serverUp) {
472
- if (await confirm('Server is already running. Restart?')) {
473
- clack.log.info('Restarting server...');
474
- try {
475
- execSync('docker compose down && docker compose up -d', { stdio: 'inherit' });
476
- clack.log.success('Server restarted');
477
- serverUp = false; // Need to wait for it to come back up
478
- } catch (err) {
479
- const output = (err.stderr || err.stdout || err.message || '').toString().trim();
480
- clack.log.warn('Failed to restart.');
481
- if (output) clack.log.error(output);
482
- clack.log.info('Fix the issue above, then run: docker compose down && docker compose up -d');
483
- }
484
- }
485
- } else {
486
- clack.log.info('Starting server...');
487
- try {
488
- execSync('docker compose up -d', { stdio: 'inherit' });
489
- clack.log.success('Server started');
490
- } catch (err) {
491
- const output = (err.stderr || err.stdout || err.message || '').toString().trim();
492
- clack.log.warn('Failed to start.');
493
- if (output) clack.log.error(output);
494
- clack.log.info('Fix the issue above, then run: docker compose up -d');
495
- }
496
- }
497
-
498
- // Poll for the server to come up (max 60 seconds)
499
- if (!serverUp) {
500
- const pollSpinner = clack.spinner();
501
- pollSpinner.start('Waiting for server to come up...');
502
-
503
- const startTime = Date.now();
504
- const timeout = 60_000;
505
-
506
- while (Date.now() - startTime < timeout) {
507
- if (await isLoginPageReady()) {
508
- serverUp = true;
509
- break;
510
- }
511
- await new Promise((r) => setTimeout(r, 2000));
512
- }
513
-
514
- if (serverUp) {
515
- pollSpinner.stop('Server is up!');
516
- } else {
517
- pollSpinner.stop('Could not detect the server after 60 seconds.');
518
- }
438
+ clack.log.info('Starting server...');
439
+ try {
440
+ execSync('docker compose up -d', { stdio: 'inherit' });
441
+ clack.log.success('Server started');
442
+ } catch (err) {
443
+ const output = (err.stderr || err.stdout || err.message || '').toString().trim();
444
+ clack.log.warn('Failed to start.');
445
+ if (output) clack.log.error(output);
446
+ clack.log.info('Fix the issue above, then run: docker compose up -d');
519
447
  }
520
448
 
521
449
  // ─── Done ─────────────────────────────────────────────────────────────
@@ -527,23 +455,16 @@ async function main() {
527
455
 
528
456
  clack.note(summary, 'Configuration');
529
457
 
530
- // Only offer the link once the server is actually serving the login page.
531
- // /admin would 401 — a fresh install has no users yet, so the root sends
532
- // them to /login where the first-user setup form is shown.
533
- if (serverUp) {
534
- clack.log.info('Create your admin account, then configure your LLM provider, API keys, and agent settings under Admin.');
535
-
536
- if (canOpenBrowser()) {
537
- const open = (await import('open')).default;
538
- const shouldOpen = await confirm(`Open ${appUrl} in your browser?`, true);
539
- if (shouldOpen) {
540
- await open(appUrl);
541
- }
542
- } else {
543
- clack.log.info(`Visit ${appUrl} to create your admin account.`);
458
+ clack.log.info('Create your admin account, then configure your LLM provider, API keys, and agent settings under Admin.');
459
+
460
+ if (canOpenBrowser()) {
461
+ const open = (await import('open')).default;
462
+ const shouldOpen = await confirm(`Open ${appUrl} in your browser?`, true);
463
+ if (shouldOpen) {
464
+ await open(appUrl);
544
465
  }
545
466
  } else {
546
- clack.log.warn(`Server didn't respond. Check docker logs, then visit ${appUrl} to create your admin account.`);
467
+ clack.log.info(`Visit ${appUrl} to create your admin account.`);
547
468
  }
548
469
 
549
470
  clack.outro('Setup complete!');