thepopebot 1.2.75-beta.13 → 1.2.75-beta.15

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.
@@ -4,13 +4,9 @@
4
4
  // Paths ending with '/' are directories (all contents are managed).
5
5
  export const MANAGED_PATHS = [
6
6
  '.github/workflows/',
7
-
8
7
  'docker-compose.yml',
9
8
  '.dockerignore',
10
9
  '.gitignore',
11
- 'agent-job/CLAUDE.md',
12
- 'event-handler/CLAUDE.md',
13
- 'skills/CLAUDE.md',
14
10
  ];
15
11
 
16
12
  export function isManaged(relPath) {
@@ -94,7 +94,12 @@ function Chat({ chatId, initialMessages = [], workspace = null, chatMode = null
94
94
  const isFinished = prevStatus.current !== "ready" && status === "ready";
95
95
  if (isMount || isFinished) {
96
96
  fetch(`/code/workspace-diff/${workspaceState.id}`).then((r) => r.json()).then((r) => {
97
- if (r.success) setDiffStats(r);
97
+ if (r.success) {
98
+ setDiffStats(r);
99
+ if (r.currentBranch) {
100
+ setWorkspaceState((prev) => prev && r.currentBranch !== prev.featureBranch ? { ...prev, featureBranch: r.currentBranch } : prev);
101
+ }
102
+ }
98
103
  }).catch(() => {
99
104
  });
100
105
  }
@@ -199,6 +204,9 @@ function Chat({ chatId, initialMessages = [], workspace = null, chatMode = null
199
204
  const data = await r.json();
200
205
  if (data.success) {
201
206
  setDiffStats(data);
207
+ if (data.currentBranch) {
208
+ setWorkspaceState((prev) => prev && data.currentBranch !== prev.featureBranch ? { ...prev, featureBranch: data.currentBranch } : prev);
209
+ }
202
210
  return data;
203
211
  }
204
212
  } catch {
@@ -118,7 +118,14 @@ export function Chat({ chatId, initialMessages = [], workspace = null, chatMode
118
118
  if (isMount || isFinished) {
119
119
  fetch(`/code/workspace-diff/${workspaceState.id}`)
120
120
  .then(r => r.json())
121
- .then(r => { if (r.success) setDiffStats(r); })
121
+ .then(r => {
122
+ if (r.success) {
123
+ setDiffStats(r);
124
+ if (r.currentBranch) {
125
+ setWorkspaceState(prev => prev && r.currentBranch !== prev.featureBranch ? { ...prev, featureBranch: r.currentBranch } : prev);
126
+ }
127
+ }
128
+ })
122
129
  .catch(() => {});
123
130
  }
124
131
  prevStatus.current = status;
@@ -244,7 +251,13 @@ export function Chat({ chatId, initialMessages = [], workspace = null, chatMode
244
251
  try {
245
252
  const r = await fetch(`/code/workspace-diff/${workspaceState.id}`);
246
253
  const data = await r.json();
247
- if (data.success) { setDiffStats(data); return data; }
254
+ if (data.success) {
255
+ setDiffStats(data);
256
+ if (data.currentBranch) {
257
+ setWorkspaceState(prev => prev && data.currentBranch !== prev.featureBranch ? { ...prev, featureBranch: data.currentBranch } : prev);
258
+ }
259
+ return data;
260
+ }
248
261
  } catch {}
249
262
  return null;
250
263
  }, [workspaceState?.id]);
@@ -293,6 +293,7 @@ function WorkspaceCommandButton({ workspaceId, diffStats, onDiffStatsRefresh, on
293
293
  onClick: onShowDiff,
294
294
  className: "text-xs leading-4 px-2.5 h-[28px] flex items-center gap-1.5 font-medium border border-border rounded-md whitespace-nowrap hover:bg-accent transition-colors cursor-pointer",
295
295
  children: [
296
+ diffStats?.currentBranch && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground truncate max-w-[120px]", title: diffStats.currentBranch, children: diffStats.currentBranch }),
296
297
  /* @__PURE__ */ jsxs("span", { className: "text-green-500", children: [
297
298
  "+",
298
299
  diffStats?.insertions ?? 0
@@ -341,6 +341,9 @@ function WorkspaceCommandButton({ workspaceId, diffStats, onDiffStatsRefresh, on
341
341
  onClick={onShowDiff}
342
342
  className="text-xs leading-4 px-2.5 h-[28px] flex items-center gap-1.5 font-medium border border-border rounded-md whitespace-nowrap hover:bg-accent transition-colors cursor-pointer"
343
343
  >
344
+ {diffStats?.currentBranch && (
345
+ <span className="text-muted-foreground truncate max-w-[120px]" title={diffStats.currentBranch}>{diffStats.currentBranch}</span>
346
+ )}
344
347
  <span className="text-green-500">+{diffStats?.insertions ?? 0}</span>
345
348
  <span className="text-destructive">-{diffStats?.deletions ?? 0}</span>
346
349
  </button>
@@ -592,7 +592,14 @@ export async function getWorkspaceDiffStats(id, authenticatedUser) {
592
592
  }
593
593
 
594
594
  updateHasChanges(id, insertions > 0 || deletions > 0);
595
- return { success: true, insertions, deletions };
595
+
596
+ // Sync featureBranch in DB if the actual branch differs
597
+ if (currentBranch && currentBranch !== workspace.featureBranch) {
598
+ const { updateFeatureBranch } = await import('../db/code-workspaces.js');
599
+ updateFeatureBranch(id, currentBranch);
600
+ }
601
+
602
+ return { success: true, insertions, deletions, currentBranch };
596
603
  } catch (err) {
597
604
  console.error(`[getWorkspaceDiffStats] workspace=${id}`, err);
598
605
  return { success: false };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thepopebot",
3
- "version": "1.2.75-beta.13",
3
+ "version": "1.2.75-beta.15",
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": {
@@ -48,6 +48,9 @@ jobs:
48
48
  cd /project && npx --yes thepopebot@latest init --no-install
49
49
  fi
50
50
 
51
+ # Install the new version into node_modules so local CLI stays current
52
+ cd /project && npm install
53
+
51
54
  # Commit any template changes from init
52
55
  git -C /project add -A
53
56
  if ! git -C /project diff --cached --quiet; then
@@ -0,0 +1,31 @@
1
+ # Project Structure
2
+
3
+ This is a [thepopebot](https://github.com/stephengpope/thepopebot) project.
4
+
5
+ ## Directories
6
+
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.
9
+ - **`event-handler/`** — Event handler configuration: chat system prompts, trigger definitions (`TRIGGERS.json`), cluster templates, and LiteLLM proxy config.
10
+ - **`skills/`** — 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.
13
+
14
+ ## Files
15
+
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.
19
+
20
+ ## Managed Files
21
+
22
+ Some files are auto-synced by `npx thepopebot init` and will be overwritten on upgrade. Do not edit these:
23
+
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`
@@ -1,34 +1,57 @@
1
1
  # agent-job/ — Agent Job Configuration
2
2
 
3
- This directory contains configuration files for Docker agent jobs. These files are **not managed** your changes are preserved across upgrades.
3
+ This directory contains your agent job configuration files — system prompts, scheduling, and self-monitoring.
4
4
 
5
- ## File Reference
5
+ ## Files
6
6
 
7
- ### System Prompts
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.
8
11
 
9
- | File | Used By | Purpose |
10
- |------|---------|---------|
11
- | `SOUL.md` | Docker agent | Agent personality, identity, and values. Included in agent job system prompts. |
12
- | `SYSTEM.md` | Docker agent | Runtime environment documentation injected into the agent's context. |
13
- | `HEARTBEAT.md` | Heartbeat cron | Self-monitoring prompt for the agent's periodic heartbeat job. |
12
+ ## Editing CRONS.json
14
13
 
15
- ### Scheduling
14
+ `CRONS.json` is a JSON array of cron job objects. Each entry needs a `name`, `schedule` (cron expression), `type`, and `enabled` flag.
16
15
 
17
- | File | Purpose |
18
- |------|---------|
19
- | `CRONS.json` | Scheduled job definitions — loaded at server startup by `node-cron`. |
16
+ There are three action types:
20
17
 
21
- ## Template Variables
18
+ **`agent`** Launches a Docker agent container to execute an LLM task.
22
19
 
23
- Config markdown files support includes and built-in variables (processed by `render-md.js` at runtime):
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
+ ```
24
29
 
25
- | Syntax | Description |
26
- |--------|-------------|
27
- | `{{ filepath.md }}` | Include another file (path relative to project root, recursive with circular detection) |
28
- | `{{datetime}}` | Current ISO timestamp |
29
- | `{{skills}}` | Dynamic bullet list of active skill descriptions from `skills/active/*/SKILL.md` frontmatter |
30
+ Optional: add `"llm_provider"` and `"llm_model"` to override the default LLM for that job.
30
31
 
31
- ## When Changes Take Effect
32
+ **`command`** Runs a shell command on the event handler (working directory: project root).
32
33
 
33
- - **Prompt files** (`.md`) — Changes take effect immediately on the next LLM call. No restart needed.
34
- - **CRONS.json** — Requires a server restart to reload schedules.
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"`.
@@ -6,51 +6,11 @@
6
6
  "job": "Read the file at agent-job/HEARTBEAT.md and complete the tasks described there.",
7
7
  "enabled": false
8
8
  },
9
- {
10
- "name": "daily-check",
11
- "schedule": "0 9 * * *",
12
- "type": "agent",
13
- "job": "Check for dependency updates in package.json and report any outdated packages.",
14
- "enabled": false
15
- },
16
9
  {
17
10
  "name": "ping",
18
11
  "schedule": "*/1 * * * *",
19
12
  "type": "command",
20
13
  "command": "echo \"pong!\"",
21
14
  "enabled": true
22
- },
23
- {
24
- "name": "cleanup-logs",
25
- "schedule": "0 0 * * 0",
26
- "type": "command",
27
- "command": "ls -la logs/",
28
- "enabled": false
29
- },
30
- {
31
- "name": "ping-status",
32
- "schedule": "*/5 * * * *",
33
- "type": "webhook",
34
- "url": "https://example.com/status",
35
- "method": "POST",
36
- "vars": { "source": "heartbeat" },
37
- "enabled": false
38
- },
39
- {
40
- "name": "health-check",
41
- "schedule": "*/10 * * * *",
42
- "type": "webhook",
43
- "url": "https://example.com/health",
44
- "method": "GET",
45
- "enabled": false
46
- },
47
- {
48
- "name": "daily-check-openai",
49
- "schedule": "0 9 * * *",
50
- "type": "agent",
51
- "job": "Check for dependency updates in package.json and report any outdated packages.",
52
- "llm_provider": "openai",
53
- "llm_model": "gpt-4o",
54
- "enabled": false
55
15
  }
56
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
 
@@ -1,30 +1,55 @@
1
- # thepopebot Agent Environment
1
+ # Agent Job Environment
2
2
 
3
- **This document describes what you are and your operating environment**
3
+ You are an autonomous AI agent running inside a Docker container on thepopebot.
4
4
 
5
- ---
5
+ ## Runtime Environment
6
6
 
7
- ## 1. What You Are
7
+ Your workspace is `/home/coding-agent/workspace` — a live git repository. Use `/tmp` for working files — downloads, intermediate data, scripts, generated files. `/tmp` is outside the repo and nothing there gets committed. If a tool downloads a file to `/tmp`, leave it there and reference it directly.
8
8
 
9
- You are **thepopebot**, an autonomous AI agent running inside a Docker container.
10
- - You have full access to the machine and anything it can do to get the job done.
9
+ 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.**
11
10
 
12
- ---
11
+ Current datetime: {{datetime}}
13
12
 
14
- ## 2. Local Docker Environment Reference
13
+ ## Directory Layout
15
14
 
16
- ### WORKDIR`/job` is a git repo
15
+ - `agents/`Agent definitions. Each subdirectory defines an agent with its own prompts.
16
+ - `agent-job/` — Runtime config: system prompts (`SOUL.md`, `SYSTEM.md`), cron schedules (`CRONS.json`), heartbeat prompt.
17
+ - `event-handler/` — Event handler config. Do not edit — managed by the event handler.
18
+ - `skills/` — Skill plugins. Active skills are symlinked into `skills/active/`.
19
+ - `data/`, `logs/` — Runtime data and job logs.
17
20
 
18
- Your working directory is `/job`. **This is a live git repository.** When your job finishes, everything inside `/job` is automatically committed and pushed via `git add -A`. You do not control this — it happens after you exit.
21
+ ## What You Can Edit
19
22
 
20
- This means: **any file you create, copy, move, or download into `/job` or any subdirectory of `/job` WILL be committed to the repository.** There are no exceptions.
23
+ - `agent-job/CRONS.json` Add, remove, or change scheduled jobs
24
+ - `agents/` — Create or remove agent definitions
25
+ - `skills/active/` — Activate or deactivate skills via symlinks
26
+ - Agent prompt files (`.md`) in `agent-job/` and `agents/`
27
+ - Reports and output files
21
28
 
22
- ### All working files go in `/tmp`
29
+ ## What You Cannot Edit
23
30
 
24
- **NEVER save, copy, move, or download files into `/job`** unless the job specifically requires changing the repository (e.g. editing source code, updating config files).
31
+ - `event-handler/` — Chat prompts, triggers, clusters, LiteLLM config
32
+ - `docker-compose.yml`, `.dockerignore`, `.gitignore` — Managed infrastructure files
33
+ - `.env` — Environment secrets
25
34
 
26
- Use `/tmp` for everything else — downloads, generated files, images, videos, scripts, intermediate data, API responses, anything you create to get the job done. `/tmp` is outside the repo and nothing there gets committed.
35
+ ## Self-Modification
27
36
 
28
- If a skill or tool downloads a file to `/tmp`, **leave it there**. Do not copy or move it into `/job`. If you need to pass that file to another tool (e.g. uploading it somewhere), reference it directly from `/tmp`.
37
+ **Add an agent** Create `agents/<name>/` with a `prompts/` 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.
29
38
 
30
- Current datetime: {{datetime}}
39
+ **Remove an agent** — Delete the `agents/<name>/` folder, remove its cron entries, update `agents/CLAUDE.md` and root `CLAUDE.md`.
40
+
41
+ **Change a schedule** — Edit `agent-job/CRONS.json` (cron expressions, enable/disable).
42
+
43
+ **Activate a skill** — Symlink from `skills/<name>/` into `skills/active/`, update root `CLAUDE.md`.
44
+
45
+ **Deactivate a skill** — Remove the symlink from `skills/active/`, update root `CLAUDE.md`.
46
+
47
+ **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.
48
+
49
+ ## Active Skills
50
+
51
+ {{skills}}
52
+
53
+ ## Orientation
54
+
55
+ 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.
File without changes
@@ -0,0 +1,5 @@
1
+ # agents/ — Custom Agent Definitions
2
+
3
+ This directory holds custom agent configurations. Each subdirectory defines an agent that can be referenced by agent jobs and cron tasks.
4
+
5
+ (No agents configured yet — add a subdirectory here to define one.)
@@ -1,117 +0,0 @@
1
- # pi-skills
2
-
3
- A collection of skills for [pi-coding-agent](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent), compatible with Claude Code, Codex CLI, Amp, and Droid.
4
-
5
- ## Installation
6
-
7
- ### pi-coding-agent
8
-
9
- ```bash
10
- # User-level (available in all projects)
11
- git clone https://github.com/badlogic/pi-skills ~/.pi/agent/skills/pi-skills
12
-
13
- # Or project-level
14
- git clone https://github.com/badlogic/pi-skills .pi/skills/pi-skills
15
- ```
16
-
17
- ### Codex CLI
18
-
19
- ```bash
20
- git clone https://github.com/badlogic/pi-skills ~/.codex/skills/pi-skills
21
- ```
22
-
23
- ### Amp
24
-
25
- Amp finds skills recursively in toolboxes:
26
-
27
- ```bash
28
- git clone https://github.com/badlogic/pi-skills ~/.config/amp/tools/pi-skills
29
- ```
30
-
31
- ### Droid (Factory)
32
-
33
- ```bash
34
- # User-level
35
- git clone https://github.com/badlogic/pi-skills ~/.factory/skills/pi-skills
36
-
37
- # Or project-level
38
- git clone https://github.com/badlogic/pi-skills .factory/skills/pi-skills
39
- ```
40
-
41
- ### Claude Code
42
-
43
- Claude Code only looks one level deep for `SKILL.md` files, so each skill folder must be directly under the skills directory. Clone the repo somewhere, then symlink individual skills:
44
-
45
- ```bash
46
- # Clone to a convenient location
47
- git clone https://github.com/badlogic/pi-skills ~/pi-skills
48
-
49
- # Symlink individual skills (user-level)
50
- mkdir -p ~/.claude/skills
51
- ln -s ~/pi-skills/brave-search ~/.claude/skills/brave-search
52
- ln -s ~/pi-skills/browser-tools ~/.claude/skills/browser-tools
53
- ln -s ~/pi-skills/gccli ~/.claude/skills/gccli
54
- ln -s ~/pi-skills/gdcli ~/.claude/skills/gdcli
55
- ln -s ~/pi-skills/gmcli ~/.claude/skills/gmcli
56
- ln -s ~/pi-skills/transcribe ~/.claude/skills/transcribe
57
- ln -s ~/pi-skills/vscode ~/.claude/skills/vscode
58
- ln -s ~/pi-skills/youtube-transcript ~/.claude/skills/youtube-transcript
59
-
60
- # Or project-level
61
- mkdir -p .claude/skills
62
- ln -s ~/pi-skills/brave-search .claude/skills/brave-search
63
- ln -s ~/pi-skills/browser-tools .claude/skills/browser-tools
64
- ln -s ~/pi-skills/gccli .claude/skills/gccli
65
- ln -s ~/pi-skills/gdcli .claude/skills/gdcli
66
- ln -s ~/pi-skills/gmcli .claude/skills/gmcli
67
- ln -s ~/pi-skills/transcribe .claude/skills/transcribe
68
- ln -s ~/pi-skills/vscode .claude/skills/vscode
69
- ln -s ~/pi-skills/youtube-transcript .claude/skills/youtube-transcript
70
- ```
71
-
72
- ## Available Skills
73
-
74
- | Skill | Description |
75
- |-------|-------------|
76
- | [brave-search](brave-search/SKILL.md) | Web search and content extraction via Brave Search |
77
- | [gccli](gccli/SKILL.md) | Google Calendar CLI for events and availability |
78
- | [gdcli](gdcli/SKILL.md) | Google Drive CLI for file management and sharing |
79
- | [gmcli](gmcli/SKILL.md) | Gmail CLI for email, drafts, and labels |
80
- | [transcribe](transcribe/SKILL.md) | Speech-to-text transcription via Groq Whisper API |
81
- | [vscode](vscode/SKILL.md) | VS Code integration for diffs and file comparison |
82
- | [youtube-transcript](youtube-transcript/SKILL.md) | Fetch YouTube video transcripts |
83
-
84
- ## Skill Format
85
-
86
- Each skill follows the pi/Claude Code format:
87
-
88
- ```markdown
89
- ---
90
- name: skill-name
91
- description: Short description shown to agent
92
- ---
93
-
94
- # Instructions
95
-
96
- Detailed instructions here...
97
- Helper files available at: skills/skill-name/
98
- ```
99
-
100
- Skills use project-root-relative paths (e.g., `skills/brave-search/search.js`).
101
-
102
- ## Requirements
103
-
104
- Some skills require additional setup. Generally, the agent will walk you through that. But if not, here you go:
105
-
106
- - **brave-search**: Requires Node.js. Run `npm install` in the skill directory.
107
- - **gccli**: Requires Node.js. Install globally with `npm install -g @mariozechner/gccli`.
108
- - **gdcli**: Requires Node.js. Install globally with `npm install -g @mariozechner/gdcli`.
109
- - **gmcli**: Requires Node.js. Install globally with `npm install -g @mariozechner/gmcli`.
110
- - **subagent**: Requires pi-coding-agent. Install globally with `npm install -g @mariozechner/pi-coding-agent`.
111
- - **transcribe**: Requires curl and a Groq API key.
112
- - **vscode**: Requires VS Code with `code` CLI in PATH.
113
- - **youtube-transcript**: Requires Node.js. Run `npm install` in the skill directory.
114
-
115
- ## License
116
-
117
- MIT