thepopebot 1.2.75-beta.2 → 1.2.75-beta.21

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 (120) hide show
  1. package/README.md +1 -1
  2. package/api/CLAUDE.md +1 -1
  3. package/api/index.js +5 -12
  4. package/bin/CLAUDE.md +1 -1
  5. package/bin/cli.js +329 -14
  6. package/bin/docker-build.js +5 -0
  7. package/bin/managed-paths.js +0 -7
  8. package/bin/sync.js +84 -0
  9. package/config/CLAUDE.md +1 -29
  10. package/config/instrumentation.js +1 -1
  11. package/lib/CLAUDE.md +3 -3
  12. package/lib/ai/CLAUDE.md +24 -3
  13. package/lib/ai/agent.js +8 -5
  14. package/lib/ai/async-channel.js +51 -0
  15. package/lib/ai/headless-stream.js +3 -0
  16. package/lib/ai/index.js +149 -173
  17. package/lib/ai/line-mappers.js +72 -9
  18. package/lib/ai/tools.js +40 -28
  19. package/lib/chat/actions.js +34 -6
  20. package/lib/chat/api.js +17 -1
  21. package/lib/chat/components/chat-header.js +4 -0
  22. package/lib/chat/components/chat-header.jsx +4 -0
  23. package/lib/chat/components/chat-input.js +1 -0
  24. package/lib/chat/components/chat-input.jsx +1 -0
  25. package/lib/chat/components/chat.js +9 -1
  26. package/lib/chat/components/chat.jsx +15 -2
  27. package/lib/chat/components/chats-page.js +3 -3
  28. package/lib/chat/components/chats-page.jsx +4 -6
  29. package/lib/chat/components/crons-page.js +1 -1
  30. package/lib/chat/components/crons-page.jsx +1 -1
  31. package/lib/chat/components/message.js +12 -4
  32. package/lib/chat/components/message.jsx +17 -4
  33. package/lib/chat/components/settings-chat-page.js +2 -1
  34. package/lib/chat/components/settings-chat-page.jsx +4 -1
  35. package/lib/chat/components/settings-coding-agents-page.js +139 -1
  36. package/lib/chat/components/settings-coding-agents-page.jsx +160 -0
  37. package/lib/chat/components/settings-jobs-page.js +13 -2
  38. package/lib/chat/components/settings-jobs-page.jsx +15 -1
  39. package/lib/chat/components/settings-secrets-layout.js +1 -1
  40. package/lib/chat/components/settings-secrets-layout.jsx +1 -1
  41. package/lib/chat/components/sidebar-history-item.js +3 -3
  42. package/lib/chat/components/sidebar-history-item.jsx +4 -6
  43. package/lib/chat/components/triggers-page.js +1 -1
  44. package/lib/chat/components/triggers-page.jsx +1 -1
  45. package/lib/cluster/actions.js +4 -4
  46. package/lib/cluster/execute.js +3 -1
  47. package/lib/code/actions.js +34 -11
  48. package/lib/code/code-page.js +40 -40
  49. package/lib/code/code-page.jsx +36 -36
  50. package/lib/code/port-forwards.js +17 -3
  51. package/lib/code/terminal-view.js +16 -0
  52. package/lib/code/terminal-view.jsx +18 -0
  53. package/lib/config.js +4 -0
  54. package/lib/cron.js +3 -3
  55. package/lib/db/api-keys.js +22 -61
  56. package/lib/db/config.js +23 -0
  57. package/lib/db/index.js +3 -1
  58. package/lib/maintenance.js +34 -11
  59. package/lib/paths.js +1 -38
  60. package/lib/tools/create-agent-job.js +0 -4
  61. package/lib/tools/docker.js +23 -16
  62. package/lib/triggers.js +4 -3
  63. package/lib/utils/render-md.js +3 -1
  64. package/package.json +2 -1
  65. package/setup/setup-ssl.mjs +414 -0
  66. package/templates/.github/workflows/rebuild-event-handler.yml +3 -0
  67. package/templates/.github/workflows/upgrade-event-handler.yml +1 -1
  68. package/templates/.gitignore.template +7 -3
  69. package/templates/.tmp/CLAUDE.md.template +5 -0
  70. package/templates/CLAUDE.md +3 -2
  71. package/templates/CLAUDE.md.template +24 -357
  72. package/templates/agent-job/CLAUDE.md.template +57 -0
  73. package/templates/agent-job/CRONS.json +16 -0
  74. package/templates/{config/agent-job → agent-job}/SOUL.md +3 -3
  75. package/templates/agent-job/SYSTEM.md +60 -0
  76. package/templates/agents/CLAUDE.md.template +54 -0
  77. package/templates/data/CLAUDE.md.template +5 -0
  78. package/templates/docker-compose.custom.yml +41 -62
  79. package/templates/docker-compose.yml +14 -21
  80. package/templates/event-handler/CLAUDE.md.template +0 -0
  81. package/templates/logs/CLAUDE.md.template +5 -0
  82. package/templates/skills/CLAUDE.md.template +57 -32
  83. package/templates/skills/active/.gitkeep +0 -0
  84. package/templates/skills/library/agent-job-secrets/SKILL.md +23 -0
  85. package/templates/skills/library/agent-job-secrets/agent-job-secrets.js +62 -0
  86. package/templates/.pi/extensions/env-sanitizer/index.ts +0 -48
  87. package/templates/.pi/extensions/env-sanitizer/package.json +0 -5
  88. package/templates/README.md +0 -75
  89. package/templates/config/CLAUDE.md.template +0 -40
  90. package/templates/config/CRONS.json +0 -56
  91. package/templates/config/agent-job/AGENT_JOB.md +0 -30
  92. package/templates/cron/CLAUDE.md.template +0 -24
  93. package/templates/docker-compose.litellm.yml +0 -82
  94. package/templates/docs/CLAUDE.md.template +0 -12
  95. package/templates/docs/CLI.md +0 -59
  96. package/templates/docs/CLUSTERS.md +0 -151
  97. package/templates/docs/CONFIGURATION.md +0 -181
  98. package/templates/docs/CRONS_AND_TRIGGERS.md +0 -132
  99. package/templates/docs/GETTING_STARTED.md +0 -64
  100. package/templates/docs/SECURITY.md +0 -61
  101. package/templates/docs/SKILLS.md +0 -113
  102. package/templates/docs/UPGRADING.md +0 -92
  103. package/templates/skills/LICENSE +0 -21
  104. package/templates/skills/README.md +0 -117
  105. package/templates/skills/agent-job-secrets/SKILL.md +0 -25
  106. package/templates/skills/agent-job-secrets/agent-job-secrets.js +0 -66
  107. package/templates/traefik-dynamic.yml.example +0 -7
  108. package/templates/triggers/CLAUDE.md.template +0 -41
  109. /package/templates/{config → agent-job}/HEARTBEAT.md +0 -0
  110. /package/templates/{cron → data}/.gitkeep +0 -0
  111. /package/templates/{logs → data/clusters}/.gitkeep +0 -0
  112. /package/templates/{triggers → data/db}/.gitkeep +0 -0
  113. /package/templates/{config/agent-job → event-handler}/SUMMARY.md +0 -0
  114. /package/templates/{config → event-handler}/TRIGGERS.json +0 -0
  115. /package/templates/{config → event-handler}/agent-chat/SYSTEM.md +0 -0
  116. /package/templates/{config/cluster → event-handler/clusters}/ROLE.md +0 -0
  117. /package/templates/{config/cluster → event-handler/clusters}/SYSTEM.md +0 -0
  118. /package/templates/{config → event-handler}/code-chat/SYSTEM.md +0 -0
  119. /package/templates/{config → event-handler}/litellm/main.yaml +0 -0
  120. /package/templates/skills/{playwright-cli → library/playwright-cli}/SKILL.md +0 -0
@@ -11,7 +11,8 @@ This directory contains files that get copied into user projects when they run `
11
11
 
12
12
  ## What belongs here
13
13
 
14
- - **User-editable config**: `config/agent-chat/SYSTEM.md`, `config/agent-job/SOUL.md`, `config/CRONS.json`, `config/TRIGGERS.json`, etc.
14
+ - **Agent job config**: `agent-job/SOUL.md`, `agent-job/CRONS.json`, etc.
15
+ - **Event handler config**: `event-handler/agent-chat/SYSTEM.md`, `event-handler/TRIGGERS.json`, etc.
15
16
  - **GitHub Actions workflows**: `.github/workflows/`
16
17
  - **Docker compose**: `docker-compose.yml`
17
18
 
@@ -30,4 +31,4 @@ If you're adding a feature to the event handler, put it in the package. Template
30
31
 
31
32
  ## Managed vs. User-Owned
32
33
 
33
- Files inside managed paths (`.github/workflows/`, etc.) are auto-synced by `init` — stale files are deleted, changed files are overwritten. Never add user-editable content to managed paths. User customization goes in `config/`.
34
+ Files inside managed paths (`.github/workflows/`, etc.) are auto-synced by `init` — stale files are deleted, changed files are overwritten. Never add user-editable content to managed paths. User customization goes in `agent-job/` and `event-handler/`.
@@ -1,368 +1,35 @@
1
- # My Agent
1
+ # Project Structure
2
2
 
3
- ## Overview
3
+ This is a [thepopebot](https://github.com/stephengpope/thepopebot) project.
4
4
 
5
- This is an autonomous AI agent powered by [thepopebot](https://github.com/stephengpope/thepopebot). It uses a **two-layer architecture**:
5
+ ## Directories
6
6
 
7
- 1. **Event Handler** A Next.js server that orchestrates everything: web UI, Telegram chat, cron scheduling, webhook triggers, and job creation.
8
- 2. **Docker Agent** A container launched locally by the event handler that runs the coding agent for autonomous task execution. Each job gets its own branch, container, and PR.
7
+ - **`agent-job/`**Agent job configuration: system prompts (`SOUL.md`, `SYSTEM.md`), heartbeat prompt, and cron schedules (`CRONS.json`).
8
+ - **`agents/`**Custom agent definitions. Each subdirectory defines an agent (see Managing Agents below).
9
+ - **`event-handler/`** — Event handler configuration: chat system prompts, trigger definitions (`TRIGGERS.json`), cluster templates, and LiteLLM proxy config.
10
+ - **`skills/library/`** — Skill plugins. Activate by symlinking into `skills/active/`.
11
+ - **`data/`** — Runtime data (SQLite database, cluster state). Not checked into git.
12
+ - **`logs/`** — Agent job logs, organized by job ID. Not checked into git.
9
13
 
10
- All core logic lives in the `thepopebot` npm package. This project contains only configuration and data — the Next.js app, `.next` build output, and all web dependencies are baked into the Docker image.
14
+ ## Files
11
15
 
12
- ## Directory Structure
13
-
14
- ```
15
- project-root/
16
- ├── CLAUDE.md # This file (project documentation)
17
- ├── README.md # User-facing orientation doc
18
- ├── .env # Infrastructure config only (gitignored)
19
- ├── package.json
20
-
21
- ├── config/ # Agent configuration (user-editable)
22
- │ ├── agent-chat/
23
- │ │ └── SYSTEM.md # Agent chat system prompt
24
- │ ├── code-chat/
25
- │ │ └── SYSTEM.md # Code workspace planning prompt
26
- │ ├── agent-job/
27
- │ │ ├── SOUL.md # Personality, identity, and values
28
- │ │ ├── AGENT_JOB.md # Agent runtime environment docs
29
- │ │ └── SUMMARY.md # Prompt for summarizing completed jobs
30
- │ ├── cluster/
31
- │ │ ├── SYSTEM.md # Cluster system prompt
32
- │ │ └── ROLE.md # Cluster role prompt
33
- │ ├── HEARTBEAT.md # Self-monitoring / heartbeat behavior
34
- │ ├── CRONS.json # Scheduled job definitions
35
- │ └── TRIGGERS.json # Webhook trigger definitions
36
-
37
- ├── .github/workflows/ # GitHub Actions
38
- ├── docker-compose.yml # Docker Compose config (MANAGED)
39
- ├── docker-compose.custom.yml # User-owned compose overrides (not managed)
40
- ├── traefik-dynamic.yml.example # Traefik TLS config template (not managed)
41
- ├── skills/ # All available agent skills
42
- │ └── active/ # Symlinks to active skills (shared by Pi + Claude Code)
43
- ├── .pi/skills → skills/active # Pi reads skills from here
44
- ├── .claude/skills → skills/active # Claude Code reads skills from here
45
- ├── cron/ # Scripts for command-type cron actions
46
- ├── triggers/ # Scripts for command-type trigger actions
47
- ├── logs/ # Per-job output (logs/<JOB_ID>/job.md + session .jsonl)
48
- ├── data/ # SQLite database (data/thepopebot.sqlite)
49
- │ └── clusters/ # Cluster workspace data (shared dirs, role dirs, logs)
50
- └── docs/ # User documentation (see docs/ for guides)
51
- ```
52
-
53
- ## Two-Layer Architecture
54
-
55
- ```
56
- ┌─────────────────────────────────────────────────────────────────────────┐
57
- │ │
58
- │ ┌──────────────────┐ │
59
- │ │ Event Handler │ ──1──► Creates agent-job/* branch │
60
- │ │ (creates job) │ ──2──► Launches Docker agent container │
61
- │ └────────▲─────────┘ │
62
- │ │ ┌──────────────────┐ │
63
- │ │ │ Docker Agent │ │
64
- │ │ │ (runs agent, │ │
65
- │ │ │ creates PR) │ │
66
- │ │ └────────┬─────────┘ │
67
- │ │ │ │
68
- │ │ 3 (creates PR) │
69
- │ │ │ │
70
- │ │ ▼ │
71
- │ │ ┌──────────────────┐ │
72
- │ │ │ GitHub │ │
73
- │ │ │ (PR opened) │ │
74
- │ │ └────────┬─────────┘ │
75
- │ │ │ │
76
- │ │ 4a (auto-merge.yml) │
77
- │ │ 4b (notify-pr-complete.yml) │
78
- │ │ │ │
79
- │ 5 (notification → web UI │ │
80
- │ and Telegram) │ │
81
- │ └────────────────────────────┘ │
82
- │ │
83
- └─────────────────────────────────────────────────────────────────────────┘
84
- ```
85
-
86
- **Event Handler** (this Next.js server): Receives requests (web UI, Telegram, webhooks, cron timers), creates jobs by launching Docker agent containers locally, and manages the web interface.
87
-
88
- **Docker Agent**: A container launched locally by the event handler that clones the job branch, runs the coding agent with the job prompt, commits results, and opens a PR. Supports multiple agent backends: Claude Code, Pi, Gemini CLI, Codex CLI, and OpenCode — configured via the Coding Agents admin page.
89
-
90
- ## Job Lifecycle
91
-
92
- 1. **Job created** — Event handler calls `createAgentJob()` (via chat, cron, trigger, or API)
93
- 2. **Branch pushed** — An `agent-job/*` branch is created with `logs/<uuid>/agent-job.config.json` containing the task config
94
- 3. **Container launched** — Event handler launches a Docker agent container **locally** via the Docker Engine API (Unix socket). No GitHub Actions runner is involved in job execution.
95
- 4. **Agent runs** — Docker agent clones the branch, builds the system prompt from config files, runs the agent with the job prompt, and logs the session to `logs/<uuid>/`
96
- 5. **PR created** — Agent commits results and opens a pull request
97
- 6. **Auto-merge** — `auto-merge.yml` (GitHub Actions, self-hosted runner) squash-merges the PR if all changed files fall within `ALLOWED_PATHS` prefixes (default: `/logs`)
98
- 7. **Notification** — `notify-pr-complete.yml` sends job results back to the event handler, which creates a notification in the web UI and sends a Telegram message
99
-
100
- ## Code Workspaces
101
-
102
- Interactive and headless browser-based coding sessions that run inside Docker containers. Launch from chat to get a full terminal environment with your configured coding agent and repo.
103
-
104
- - **Multi-agent support** — Choose from Claude Code, Pi, Gemini CLI, Codex CLI, or OpenCode as the workspace agent backend
105
- - **Interactive mode** — Browser-based terminal at `/code/{id}` with shell tabs and toolbar actions (commit, merge, reconnect)
106
- - **Headless mode** — Autonomous task execution: agent runs in prompt mode, commits changes, and creates a PR
107
- - **Persistence** — Workspace data in Docker volumes; stopped containers are auto-recovered
108
- - **Linked to chat** — Workspace context flows from chat; session summaries flow back on close
109
- - **Container monitoring** — Live Docker container stats via the Containers admin page
110
-
111
- Configuration: requires Docker socket access, `GH_TOKEN`, and agent-specific credentials (OAuth tokens or API keys) configured via `/admin/event-handler/coding-agents`.
112
-
113
- ## Chat Modes
114
-
115
- The chat interface has two primary modes, stored per-chat in `chats.chatMode`:
116
-
117
- **Agent mode** (`chatMode: 'agent'`) — For interacting with the PopeBot agent. Three sub-modes:
118
- - **plan** — `coding_agent` tool runs in read-only permission mode (investigation, exploration)
119
- - **code** — `coding_agent` tool runs in write permission mode (make changes)
120
- - **job** — `agent_job` tool dispatches an autonomous Docker container task (fire-and-forget)
121
-
122
- **Code mode** (`chatMode: 'code'`) — For working on a specific GitHub repo. Two sub-modes:
123
- - **plan** — Read-only investigation of the selected repo
124
- - **code** — Write changes to the selected repo
125
-
126
- Sub-modes are selected via a dropdown in the chat input. The LLM receives a `[chat mode: X]` suffix on each user message to know which tool to invoke.
127
-
128
- ## Cluster Workspaces
129
-
130
- Multi-role agent teams that collaborate via shared directories. Create and manage at `/clusters`.
131
-
132
- - **Roles** — Each role has its own prompt, trigger config, max concurrency, and working directory
133
- - **Shared directories** — Named folders under `shared/` accessible to all roles
134
- - **Triggers** — Manual (click), webhook (POST with payload), cron (scheduled), file watch (react to changes)
135
- - **Concurrency** — Per-role container limits; triggers are rejected when at capacity
136
- - **Console** — Live container status, resource usage, streaming logs at `/clusters`
137
- - **Prompts** — Customizable via `config/cluster/SYSTEM.md` (shared) and `config/cluster/ROLE.md` (per-role template)
138
- - **Data** — Stored under `data/clusters/cluster-{id}/`
139
-
140
- ## Action Types
141
-
142
- Both cron jobs and webhook triggers use the same dispatch system. Every action has a `type` field:
143
-
144
- | | `agent` (default) | `command` | `webhook` |
145
- |---|---|---|---|
146
- | **Uses LLM** | Yes — spins up Docker agent | No | No |
147
- | **Runtime** | Minutes to hours | Milliseconds to seconds | Milliseconds to seconds |
148
- | **Cost** | LLM API calls | Free (runs on event handler) | Free (runs on event handler) |
149
- | **Use case** | Tasks that need to think, reason, write code | Shell scripts, file operations | Call external APIs, forward webhooks |
150
-
151
- If the task needs to *think*, use `agent`. If it just needs to *do*, use `command`. If it needs to *call an external service*, use `webhook`.
152
-
153
- ### Agent action
154
- ```json
155
- { "type": "agent", "job": "Analyze the logs and write a summary report" }
156
- ```
157
- Creates a Docker Agent job. The `job` string is passed as-is to the LLM as its task prompt.
158
-
159
- ### Command action
160
- ```json
161
- { "type": "command", "command": "node cleanup.js --older-than 7d" }
162
- ```
163
- Runs a shell command on the event handler. Working directory: `cron/` for crons, `triggers/` for triggers.
164
-
165
- ### Webhook action
166
- ```json
167
- {
168
- "type": "webhook",
169
- "url": "https://api.example.com/notify",
170
- "method": "POST",
171
- "headers": { "Authorization": "Bearer token" },
172
- "vars": { "source": "my-agent" }
173
- }
174
- ```
175
- Makes an HTTP request. `GET` skips the body. `POST` (default) sends `{ ...vars }` or `{ ...vars, data: <incoming payload> }` when triggered by a webhook.
176
-
177
- ## Cron Jobs
178
-
179
- Defined in `config/CRONS.json`, loaded at server startup by `node-cron`.
180
-
181
- ```json
182
- [
183
- {
184
- "name": "Daily Check",
185
- "schedule": "0 9 * * *",
186
- "type": "agent",
187
- "job": "Review recent activity and summarize findings",
188
- "enabled": true
189
- }
190
- ]
191
- ```
192
-
193
- | Field | Required | Description |
194
- |-------|----------|-------------|
195
- | `name` | Yes | Display name |
196
- | `schedule` | Yes | Cron expression (e.g., `0 9 * * *` = daily at 9am) |
197
- | `type` | No | `agent` (default), `command`, or `webhook` |
198
- | `job` | For agent | Task prompt passed to the LLM |
199
- | `command` | For command | Shell command (runs in `cron/` directory) |
200
- | `url` | For webhook | Target URL |
201
- | `method` | For webhook | `GET` or `POST` (default: `POST`) |
202
- | `headers` | For webhook | Custom request headers |
203
- | `vars` | For webhook | Key-value pairs merged into request body |
204
- | `enabled` | No | Set `false` to disable (default: `true`) |
205
- | `llm_provider` | No | Override LLM provider for this cron (agent type only) |
206
- | `llm_model` | No | Override LLM model for this cron (agent type only) |
207
-
208
- ## Webhook Triggers
209
-
210
- Defined in `config/TRIGGERS.json`, loaded at server startup. Triggers fire on POST requests to watched paths (after auth, before route handler, fire-and-forget).
211
-
212
- ```json
213
- [
214
- {
215
- "name": "GitHub Push",
216
- "watch_path": "/webhook/github-push",
217
- "enabled": true,
218
- "actions": [
219
- {
220
- "type": "agent",
221
- "job": "Review the push to {{body.ref}}: {{body.head_commit.message}}"
222
- }
223
- ]
224
- }
225
- ]
226
- ```
227
-
228
- | Field | Required | Description |
229
- |-------|----------|-------------|
230
- | `name` | Yes | Display name |
231
- | `watch_path` | Yes | URL path to watch (e.g., `/webhook/github-push`) |
232
- | `actions` | Yes | Array of actions to fire (same fields as cron actions) |
233
- | `enabled` | No | Set `false` to disable (default: `true`) |
234
-
235
- **Template tokens** for `job` and `command` strings:
236
-
237
- | Token | Resolves to |
238
- |-------|-------------|
239
- | `{{body}}` | Entire request body as JSON |
240
- | `{{body.field}}` | Nested field from request body |
241
- | `{{query}}` | All query parameters as JSON |
242
- | `{{query.field}}` | Specific query parameter |
243
- | `{{headers}}` | All request headers as JSON |
244
- | `{{headers.field}}` | Specific request header |
245
-
246
- ## API Endpoints
247
-
248
- All API routes are under `/api/`, handled by the catch-all route.
249
-
250
- | Endpoint | Method | Auth | Purpose |
251
- |----------|--------|------|---------|
252
- | `/api/create-agent-job` | POST | `x-api-key` | Create a new autonomous agent job |
253
- | `/api/telegram/webhook` | POST | `TELEGRAM_WEBHOOK_SECRET` | Telegram bot webhook |
254
- | `/api/telegram/register` | POST | `x-api-key` | Register Telegram webhook URL |
255
- | `/api/github/webhook` | POST | `GH_WEBHOOK_SECRET` | Receive notifications from GitHub Actions |
256
- | `/api/agent-jobs/status` | GET | `x-api-key` | Check status of agent jobs (query: `?agent_job_id=`) |
257
- | `/api/cluster/{clusterId}/role/{roleId}/webhook` | POST | `x-api-key` | Trigger a cluster role execution |
258
- | `/api/ping` | GET | Public | Health check |
259
-
260
- **`x-api-key`**: Database-backed API keys generated through the web UI (Settings > Secrets). Keys are SHA-256 hashed, verified with timing-safe comparison. Format: `tpb_` prefix + 64 hex characters.
261
-
262
- ## Web Interface
263
-
264
- Accessible after login at `APP_URL`. Sidebar navigation: `/` (chat), `/chats` (history), `/chat/[chatId]` (resume chat), `/code/{id}` (code workspace terminal), `/clusters` (cluster workspaces), `/containers` (Docker container monitoring), `/pull-requests` (PR approvals), `/notifications`, `/profile` (self-service email/password), `/login` (auth / first-time admin setup).
265
-
266
- Admin panel tabs: Event Handler, GitHub, Users, Crons, Triggers, General. Event Handler sub-tabs: `/admin/event-handler/llms` (LLM provider credentials), `/admin/event-handler/chat` (chat model selection), `/admin/event-handler/coding-agents` (multi-agent config), `/admin/event-handler/agent-jobs` (custom agent env vars), `/admin/event-handler/webhooks`, `/admin/event-handler/telegram`, `/admin/event-handler/voice`. Other admin: `/admin/github` (tokens, secrets, variables), `/admin/api-keys`, `/admin/users`, `/admin/crons`, `/admin/triggers`, `/admin/general`.
267
-
268
- ## Authentication
269
-
270
- NextAuth v5 with Credentials provider (email/password), JWT in httpOnly cookies. First visit creates admin account. Browser UI uses fetch route handlers with `auth()` session check. API routes use `x-api-key` header. SSE streaming endpoints (`/stream/chat`, `/stream/containers`, `/stream/cluster/*/logs`) also use `auth()` session check.
271
-
272
- ## Database
273
-
274
- SQLite via Drizzle ORM at `data/thepopebot.sqlite`. Auto-initialized and auto-migrated on server startup. Tables: `users`, `chats` (includes `chat_mode`), `messages`, `code_workspaces` (includes `feature_branch`, `has_changes`), `notifications`, `subscriptions`, `clusters`, `cluster_roles`, `settings`. Column naming: camelCase in JS → snake_case in SQL.
275
-
276
- The `settings` table is the primary configuration store with 4 types: `config` (plaintext prefs), `config_secret` (encrypted API keys/tokens), `llm_provider` (custom provider configs), `agent_job_secret` (custom env vars for agent containers). All application config is DB-backed — configured via the admin UI, not `.env`.
277
-
278
- ## GitHub Actions Workflows
279
-
280
- GitHub Actions handle **PR lifecycle and server maintenance only** — agent jobs execute as local Docker containers, not GitHub runners. Workflows run on self-hosted runners (`docker-compose.yml` includes a runner service).
281
-
282
- | Workflow | Trigger | Purpose |
283
- |----------|---------|---------|
284
- | `auto-merge.yml` | Job PR opened | Squash-merges if changes are within `ALLOWED_PATHS` |
285
- | `notify-pr-complete.yml` | After `auto-merge.yml` | Sends job completion notification to event handler |
286
- | `rebuild-event-handler.yml` | Push to `main` | Rebuilds server (fast path or Docker restart) |
287
- | `upgrade-event-handler.yml` | Manual `workflow_dispatch` | Creates PR to upgrade thepopebot package |
288
-
289
- ## Configuration
290
-
291
- All application configuration is **DB-backed** in the `settings` table, managed via the admin UI. The `.env` file holds only infrastructure keys needed before the database is available.
292
-
293
- ### Infrastructure (.env)
294
-
295
- | Variable | Description | Required |
296
- |----------|-------------|----------|
297
- | `APP_URL` | Public URL for webhooks and Telegram | Yes |
298
- | `AUTH_SECRET` | NextAuth session encryption (auto-generated by init) | Yes |
299
- | `GH_TOKEN` | GitHub PAT for creating branches/files | Yes |
300
- | `GH_OWNER` | GitHub repository owner | Yes |
301
- | `GH_REPO` | GitHub repository name | Yes |
302
- | `APP_HOSTNAME` | Hostname extracted from APP_URL (for Traefik) | Yes |
303
- | `DATABASE_PATH` | Override SQLite DB location | No |
304
- | `COMPOSE_FILE` | Override docker-compose file (e.g. `docker-compose.custom.yml`) | No |
305
-
306
- ### Application Config (Settings DB)
307
-
308
- Configured via the admin UI at `/admin/event-handler/`. All values stored encrypted or plaintext in the `settings` table.
309
-
310
- **LLM Provider** (`/admin/event-handler/chat`): `LLM_PROVIDER`, `LLM_MODEL`, `LLM_MAX_TOKENS` (default 4096). 9 built-in providers: `anthropic` (default), `openai`, `google`, `deepseek`, `minimax`, `mistral`, `xai`, `kimi`, `openrouter`. Custom OpenAI-compatible providers can be added via `/admin/event-handler/llms`.
311
-
312
- **Provider API Keys** (`/admin/event-handler/llms`): `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GOOGLE_API_KEY`, `DEEPSEEK_API_KEY`, `MINIMAX_API_KEY`, `MISTRAL_API_KEY`, `XAI_API_KEY`, `MOONSHOT_API_KEY`, `OPENROUTER_API_KEY`.
313
-
314
- **Coding Agents** (`/admin/event-handler/coding-agents`): `CODING_AGENT` (global default: `claude-code`). Per-agent config for 5 backends: claude-code, pi, gemini-cli, codex-cli, opencode — including auth mode (OAuth/API key), provider, and model.
315
-
316
- **Agent Job Secrets** (`/admin/event-handler/agent-jobs`): Custom environment variables injected into agent containers. Stored as `type: 'agent_job_secret'` in the DB. These replace the old `AGENT_LLM_*` GitHub secrets system.
317
-
318
- **Other**: `AGENT_BACKEND` (agent job runner), `TELEGRAM_BOT_TOKEN`, `TELEGRAM_CHAT_ID`, `TELEGRAM_WEBHOOK_SECRET`, `GH_WEBHOOK_SECRET`.
319
-
320
- ### GitHub Repository Variables
321
-
322
- Used by GitHub Actions workflows (PR lifecycle only, not job execution):
323
-
324
- | Variable | Description | Default |
325
- |----------|-------------|---------|
326
- | `APP_URL` | Public URL for the event handler | Required |
327
- | `AUTO_MERGE` | Set to `"false"` to disable auto-merge | Enabled |
328
- | `ALLOWED_PATHS` | Comma-separated path prefixes for auto-merge | `/logs` |
329
- | `LLM_PROVIDER` | LLM provider (synced from setup) | `anthropic` |
330
- | `LLM_MODEL` | LLM model name (synced from setup) | Provider default |
331
-
332
- ### GitHub Repository Secrets
333
-
334
- Synced during setup for GitHub Actions workflows. The event handler reads credentials from the **DB**, not GitHub secrets.
335
-
336
- | Secret | Purpose |
337
- |--------|---------|
338
- | `AGENT_GH_TOKEN` | GitHub PAT for agent containers (used by workflows) |
339
- | `AGENT_ANTHROPIC_API_KEY` | Anthropic key (synced from DB during setup) |
340
- | `GH_WEBHOOK_SECRET` | Webhook auth for notification callbacks |
16
+ - **`docker-compose.yml`** — Container definitions for the event handler and LiteLLM proxy. Managed — do not edit.
17
+ - **`docker-compose.custom.yml`** — Your Docker Compose overrides. Merged with the main compose file.
18
+ - **`.env`** — Environment variables (API keys, secrets). Never committed to git.
341
19
 
342
20
  ## Managed Files
343
21
 
344
- The following paths are auto-synced by `thepopebot init` and `thepopebot upgrade`. **Do not edit them** — changes will be overwritten on package updates: `.github/workflows/`, `docker-compose.yml`, `.dockerignore`, `.gitignore`, `CLAUDE.md`, `config/CLAUDE.md`, `skills/CLAUDE.md`, `cron/CLAUDE.md`, `triggers/CLAUDE.md`, `docs/CLAUDE.md`.
345
-
346
- To customize Docker Compose config without losing changes on upgrade, set `COMPOSE_FILE=docker-compose.custom.yml` in `.env`. The custom file is scaffolded by init but never overwritten.
347
-
348
- The Next.js app and `.next` build output are baked into the Docker image — they do not exist in user projects.
349
-
350
- ## Customization
351
-
352
- User-editable config files in `config/`: `agent-chat/SYSTEM.md` (agent chat system prompt), `code-chat/SYSTEM.md` (code workspace planning), `agent-job/SOUL.md` (personality), `agent-job/AGENT_JOB.md` (runtime docs), `agent-job/SUMMARY.md` (job summaries), `cluster/SYSTEM.md` (cluster system prompt), `cluster/ROLE.md` (cluster role prompt), `HEARTBEAT.md` (self-monitoring), `CRONS.json` (scheduled jobs), `TRIGGERS.json` (webhook triggers).
353
-
354
- To customize Docker Compose (TLS, ports, volumes, extra services), edit `docker-compose.custom.yml` and set `COMPOSE_FILE=docker-compose.custom.yml` in `.env`. For Tailscale TLS, copy `traefik-dynamic.yml.example` to `traefik-dynamic.yml` and follow the instructions inside.
355
-
356
- Skills in `skills/` are activated by symlinking into `skills/active/`. Both `.pi/skills` and `.claude/skills` point to `skills/active/`. Scripts for command-type actions go in `cron/` and `triggers/`.
357
-
358
- For detailed user guides, see the `docs/` directory.
22
+ Some files are auto-synced by `npx thepopebot init` and will be overwritten on upgrade. Do not edit these:
359
23
 
360
- ### Markdown includes and variables
24
+ - `.github/workflows/` CI/CD workflows
25
+ - `docker-compose.yml`
26
+ - `.dockerignore`
27
+ - `.gitignore`
28
+ - `agent-job/CLAUDE.md`
29
+ - `agents/CLAUDE.md`
30
+ - `event-handler/CLAUDE.md`
31
+ - `skills/CLAUDE.md`
361
32
 
362
- Config markdown files support includes and built-in variables (processed by the package's `render-md.js`):
33
+ ## Agents
363
34
 
364
- | Syntax | Description |
365
- |--------|-------------|
366
- | `{{ filepath.md }}` | Include another file (relative to project root, recursive with circular detection) |
367
- | `{{datetime}}` | Current ISO timestamp |
368
- | `{{skills}}` | Dynamic bullet list of active skill descriptions from `skills/active/*/SKILL.md` frontmatter — never hardcode skill names, this is resolved at runtime |
35
+ (No agents configured yet.)
@@ -0,0 +1,57 @@
1
+ # agent-job/ — Agent Job Configuration
2
+
3
+ This directory contains your agent job configuration files — system prompts, scheduling, and self-monitoring.
4
+
5
+ ## Files
6
+
7
+ - **`SOUL.md`** — Agent personality, identity, and values. Included in every agent job system prompt.
8
+ - **`SYSTEM.md`** — Runtime environment documentation injected into the agent's context.
9
+ - **`HEARTBEAT.md`** — Prompt for the agent's periodic heartbeat cron job.
10
+ - **`CRONS.json`** — Scheduled job definitions, loaded at server startup.
11
+
12
+ ## Editing CRONS.json
13
+
14
+ `CRONS.json` is a JSON array of cron job objects. Each entry needs a `name`, `schedule` (cron expression), `type`, and `enabled` flag.
15
+
16
+ There are three action types:
17
+
18
+ **`agent`** — Launches a Docker agent container to execute an LLM task.
19
+
20
+ ```json
21
+ {
22
+ "name": "heartbeat",
23
+ "schedule": "*/30 * * * *",
24
+ "type": "agent",
25
+ "job": "Read agent-job/HEARTBEAT.md and complete the tasks described there.",
26
+ "enabled": false
27
+ }
28
+ ```
29
+
30
+ Optional: add `"llm_provider"` and `"llm_model"` to override the default LLM for that job.
31
+
32
+ **`command`** — Runs a shell command on the event handler (working directory: project root).
33
+
34
+ ```json
35
+ {
36
+ "name": "ping",
37
+ "schedule": "*/1 * * * *",
38
+ "type": "command",
39
+ "command": "echo \"pong!\"",
40
+ "enabled": true
41
+ }
42
+ ```
43
+
44
+ **`webhook`** — Makes an HTTP request. `POST` (default) sends `vars` as the body; `GET` skips the body.
45
+
46
+ ```json
47
+ {
48
+ "name": "health-check",
49
+ "schedule": "*/10 * * * *",
50
+ "type": "webhook",
51
+ "url": "https://example.com/health",
52
+ "method": "GET",
53
+ "enabled": false
54
+ }
55
+ ```
56
+
57
+ Optional webhook fields: `"method"` (default `POST`), `"headers"`, `"vars"`.
@@ -0,0 +1,16 @@
1
+ [
2
+ {
3
+ "name": "heartbeat",
4
+ "schedule": "*/30 * * * *",
5
+ "type": "agent",
6
+ "job": "Read the file at agent-job/HEARTBEAT.md and complete the tasks described there.",
7
+ "enabled": false
8
+ },
9
+ {
10
+ "name": "ping",
11
+ "schedule": "*/1 * * * *",
12
+ "type": "command",
13
+ "command": "echo \"pong!\"",
14
+ "enabled": true
15
+ }
16
+ ]
@@ -1,15 +1,15 @@
1
- # thepopebot Soul
1
+ # Agent Job Soul
2
2
 
3
3
  ## Identity
4
4
 
5
- You are a diligent and capable AI worker. You approach tasks with focus, patience, and craftsmanship.
5
+ You are a diligent and capable AI worker doing an job. You approach tasks with focus, patience, and craftsmanship.
6
6
 
7
7
  ## Personality Traits
8
8
 
9
9
  - **Methodical**: You work through problems systematically, step by step
10
10
  - **Reliable**: You follow through on commitments and complete what I start
11
11
  - **Curious**: You explore and learn from the codebase I work with
12
- - **Working Style**: You prefer to plan before acting
12
+ - **Working Style**: You plan before acting
13
13
 
14
14
  ## Values
15
15
 
@@ -0,0 +1,60 @@
1
+ # Agent Job Environment
2
+
3
+ You are an autonomous AI agent running inside a Docker container on thepopebot.
4
+
5
+ ## Runtime Environment
6
+
7
+ Your workspace is `/home/coding-agent/workspace` — a live git repository.
8
+
9
+ ## Temporary Files
10
+ Use `/home/coding-agent/workspace/.tmp/` for working files — downloads, screenshots, intermediate data, scripts, generated files. `/home/coding-agent/workspace/.tmp/` is gitignored and nothing there gets committed. If a tool downloads a file, save it to `/home/coding-agent/workspace/.tmp/` and reference it directly.
11
+
12
+ **DO NOT USE** `/tmp` because that will leak and waste disk space from writing extra layers to the container.
13
+
14
+ Everything in the workspace is automatically committed and pushed when your job finishes. You do not control this. Be intentional about what you put here — **any file you create, move, or download into the workspace WILL be committed.**
15
+
16
+ ## Directory Layout
17
+
18
+ - `agents/` — Agent definitions. Each subdirectory defines an agent with its own prompts.
19
+ - `agent-job/` — Runtime config: system prompts (`SOUL.md`, `SYSTEM.md`), cron schedules (`CRONS.json`), heartbeat prompt.
20
+ - `event-handler/` — Event handler config. Do not edit — managed by the event handler.
21
+ - `skills/library/` — Skill plugins. Active skills are symlinked into `skills/active/`.
22
+ - `data/`, `logs/` — Runtime data and job logs.
23
+
24
+ ## What You Can Edit
25
+
26
+ - `agent-job/CRONS.json` — Add, remove, or change scheduled jobs
27
+ - `agents/` — Create or remove agent definitions
28
+ - `skills/active/` — Activate or deactivate skills via symlinks
29
+ - Agent prompt files (`.md`) in `agent-job/` and `agents/`
30
+ - Reports and output files
31
+
32
+ ## What You Cannot Edit
33
+
34
+ - `event-handler/` — Chat prompts, triggers, clusters, LiteLLM config
35
+ - `docker-compose.yml`, `.dockerignore`, `.gitignore` — Managed infrastructure files
36
+ - `.env` — Environment secrets
37
+
38
+ ## Self-Modification
39
+
40
+ **Add an agent** — Create `agents/<name>/` with a `jobs/` subfolder, add a cron entry in `agent-job/CRONS.json` pointing to the prompt file, update `agents/CLAUDE.md` to document it, update root `CLAUDE.md` to reflect the new agent.
41
+
42
+ **Remove an agent** — Delete the `agents/<name>/` folder, remove its cron entries, update `agents/CLAUDE.md` and root `CLAUDE.md`.
43
+
44
+ **Change a schedule** — Edit `agent-job/CRONS.json` (cron expressions, enable/disable).
45
+
46
+ **Activate a skill** — Symlink from `skills/library/<name>/` into `skills/active/`, update root `CLAUDE.md`.
47
+
48
+ **Deactivate a skill** — Remove the symlink from `skills/active/`, update root `CLAUDE.md`.
49
+
50
+ **Keep CLAUDE.md files current** — When you change the structure of the instance (add/remove agents, change schedules, activate skills), update the root `CLAUDE.md` and any affected folder-level `CLAUDE.md` files so the next agent has an accurate picture.
51
+
52
+ ## Active Skills
53
+
54
+ {{skills}}
55
+
56
+ ## Orientation
57
+
58
+ Read the root `CLAUDE.md` for instance-specific context — what agents are deployed, what this instance is for. Read the `CLAUDE.md` in each folder you work in for local conventions.
59
+
60
+ Current datetime: {{datetime}}
@@ -0,0 +1,54 @@
1
+ # agents/ — Custom Agent Definitions
2
+
3
+ ## Adding an Agent
4
+
5
+ Each subdirectory defines an agent. Create a folder with a `SYSTEM.md` file:
6
+
7
+ ```
8
+ agents/
9
+ └── my-agent/
10
+ └── SYSTEM.md # System prompt — identity, instructions, constraints
11
+ ```
12
+
13
+ `SYSTEM.md` is the agent's system prompt. Write it in markdown addressed to the agent (e.g. "You are a code reviewer...").
14
+
15
+ For agents with multiple complex tasks, add a `jobs/` subfolder:
16
+
17
+ ```
18
+ agents/
19
+ └── my-agent/
20
+ ├── SYSTEM.md
21
+ └── jobs/
22
+ ├── weekly-report.md
23
+ └── cleanup.md
24
+ ```
25
+
26
+ ## Scheduling
27
+
28
+ Add a cron entry in `agent-job/CRONS.json`:
29
+
30
+ ```json
31
+ {
32
+ "name": "my-agent-daily",
33
+ "schedule": "0 9 * * *",
34
+ "type": "agent",
35
+ "job": "Read agents/my-agent/SYSTEM.md and follow the instructions there.",
36
+ "enabled": true
37
+ }
38
+ ```
39
+
40
+ For job-specific prompts, chain the reads:
41
+
42
+ ```json
43
+ {
44
+ "name": "my-agent-report",
45
+ "schedule": "0 9 * * 1",
46
+ "type": "agent",
47
+ "job": "Read agents/my-agent/SYSTEM.md for context, then read agents/my-agent/prompts/weekly-report.md and complete that task.",
48
+ "enabled": true
49
+ }
50
+ ```
51
+
52
+ ## Removing an Agent
53
+
54
+ Delete the `agents/<name>/` folder and remove its cron entries from `agent-job/CRONS.json`.
@@ -0,0 +1,5 @@
1
+ # Data Directory
2
+
3
+ Runtime data including the SQLite database (`thepopebot.sqlite`) and cluster state. Created automatically on server start.
4
+
5
+ Not checked into git.