@harbinger-ai/harbinger 0.1.0

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 (317) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +406 -0
  3. package/agents/README.md +76 -0
  4. package/agents/_template/CONFIG.yaml +7 -0
  5. package/agents/_template/HEARTBEAT.md +59 -0
  6. package/agents/_template/IDENTITY.md +4 -0
  7. package/agents/_template/SKILLS.md +1 -0
  8. package/agents/_template/SOUL.md +25 -0
  9. package/agents/_template/TOOLS.md +3 -0
  10. package/agents/binary-reverser/CONFIG.yaml +21 -0
  11. package/agents/binary-reverser/HEARTBEAT.md +65 -0
  12. package/agents/binary-reverser/IDENTITY.md +1 -0
  13. package/agents/binary-reverser/SKILLS.md +1 -0
  14. package/agents/binary-reverser/SOUL.md +23 -0
  15. package/agents/binary-reverser/TOOLS.md +99 -0
  16. package/agents/browser-agent/CONFIG.yaml +20 -0
  17. package/agents/browser-agent/HEARTBEAT.md +79 -0
  18. package/agents/browser-agent/IDENTITY.md +5 -0
  19. package/agents/browser-agent/SKILLS.md +86 -0
  20. package/agents/browser-agent/SOUL.md +23 -0
  21. package/agents/browser-agent/TOOLS.md +186 -0
  22. package/agents/cloud-infiltrator/CONFIG.yaml +22 -0
  23. package/agents/cloud-infiltrator/HEARTBEAT.md +78 -0
  24. package/agents/cloud-infiltrator/IDENTITY.md +1 -0
  25. package/agents/cloud-infiltrator/SKILLS.md +1 -0
  26. package/agents/cloud-infiltrator/SOUL.md +23 -0
  27. package/agents/cloud-infiltrator/TOOLS.md +68 -0
  28. package/agents/coding-assistant/CONFIG.yaml +22 -0
  29. package/agents/coding-assistant/HEARTBEAT.md +57 -0
  30. package/agents/coding-assistant/IDENTITY.md +5 -0
  31. package/agents/coding-assistant/SKILLS.md +69 -0
  32. package/agents/coding-assistant/SOUL.md +60 -0
  33. package/agents/coding-assistant/TOOLS.md +168 -0
  34. package/agents/learning-agent/CONFIG.yaml +21 -0
  35. package/agents/learning-agent/HEARTBEAT.md +63 -0
  36. package/agents/learning-agent/IDENTITY.md +5 -0
  37. package/agents/learning-agent/SKILLS.md +86 -0
  38. package/agents/learning-agent/SOUL.md +77 -0
  39. package/agents/learning-agent/TOOLS.md +145 -0
  40. package/agents/maintainer/CONFIG.yaml +31 -0
  41. package/agents/maintainer/HEARTBEAT.md +28 -0
  42. package/agents/maintainer/IDENTITY.md +33 -0
  43. package/agents/maintainer/SKILLS.md +24 -0
  44. package/agents/maintainer/SOUL.md +61 -0
  45. package/agents/maintainer/TOOLS.md +29 -0
  46. package/agents/maintainer/lib/engine.js +279 -0
  47. package/agents/maintainer/lib/safe-fixer.js +183 -0
  48. package/agents/morning-brief/CONFIG.yaml +22 -0
  49. package/agents/morning-brief/HEARTBEAT.md +60 -0
  50. package/agents/morning-brief/IDENTITY.md +5 -0
  51. package/agents/morning-brief/SKILLS.md +56 -0
  52. package/agents/morning-brief/SOUL.md +64 -0
  53. package/agents/morning-brief/TOOLS.md +112 -0
  54. package/agents/osint-detective/CONFIG.yaml +24 -0
  55. package/agents/osint-detective/HEARTBEAT.md +66 -0
  56. package/agents/osint-detective/IDENTITY.md +1 -0
  57. package/agents/osint-detective/SKILLS.md +1 -0
  58. package/agents/osint-detective/SOUL.md +23 -0
  59. package/agents/osint-detective/TOOLS.md +81 -0
  60. package/agents/recon-scout/CONFIG.yaml +22 -0
  61. package/agents/recon-scout/HEARTBEAT.md +79 -0
  62. package/agents/recon-scout/IDENTITY.md +1 -0
  63. package/agents/recon-scout/SKILLS.md +1 -0
  64. package/agents/recon-scout/SOUL.md +23 -0
  65. package/agents/recon-scout/TOOLS.md +93 -0
  66. package/agents/report-writer/CONFIG.yaml +21 -0
  67. package/agents/report-writer/HEARTBEAT.md +63 -0
  68. package/agents/report-writer/IDENTITY.md +1 -0
  69. package/agents/report-writer/SKILLS.md +1 -0
  70. package/agents/report-writer/SOUL.md +23 -0
  71. package/agents/report-writer/TOOLS.md +69 -0
  72. package/agents/shared/README.md +13 -0
  73. package/agents/web-hacker/CONFIG.yaml +24 -0
  74. package/agents/web-hacker/HEARTBEAT.md +78 -0
  75. package/agents/web-hacker/IDENTITY.md +1 -0
  76. package/agents/web-hacker/SKILLS.md +1 -0
  77. package/agents/web-hacker/SOUL.md +23 -0
  78. package/agents/web-hacker/TOOLS.md +86 -0
  79. package/api/CLAUDE.md +19 -0
  80. package/api/index.js +274 -0
  81. package/bin/cli.js +620 -0
  82. package/bin/local.sh +31 -0
  83. package/bin/postinstall.js +63 -0
  84. package/config/index.js +24 -0
  85. package/config/instrumentation.js +93 -0
  86. package/drizzle/0000_initial.sql +52 -0
  87. package/drizzle/0001_bounty_and_registry.sql +82 -0
  88. package/drizzle/0002_sync_columns.sql +7 -0
  89. package/drizzle/0003_graceful_bloodscream.sql +86 -0
  90. package/drizzle/meta/0000_snapshot.json +321 -0
  91. package/drizzle/meta/0003_snapshot.json +878 -0
  92. package/drizzle/meta/_journal.json +34 -0
  93. package/drizzle/relations.ts +3 -0
  94. package/drizzle/schema.ts +145 -0
  95. package/lib/actions.js +47 -0
  96. package/lib/agents.js +166 -0
  97. package/lib/ai/agent.js +96 -0
  98. package/lib/ai/autonomous-engine.js +261 -0
  99. package/lib/ai/index.js +359 -0
  100. package/lib/ai/model-router.js +254 -0
  101. package/lib/ai/model.js +73 -0
  102. package/lib/ai/tools.js +84 -0
  103. package/lib/auth/actions.js +28 -0
  104. package/lib/auth/config.js +27 -0
  105. package/lib/auth/edge-config.js +27 -0
  106. package/lib/auth/index.js +27 -0
  107. package/lib/auth/middleware.js +53 -0
  108. package/lib/bounty/actions.js +119 -0
  109. package/lib/bounty/findings.js +64 -0
  110. package/lib/bounty/programs.js +34 -0
  111. package/lib/bounty/sync-targets.js +267 -0
  112. package/lib/bounty/targets.js +33 -0
  113. package/lib/channels/base.js +56 -0
  114. package/lib/channels/index.js +15 -0
  115. package/lib/channels/telegram.js +148 -0
  116. package/lib/chat/actions.js +288 -0
  117. package/lib/chat/api.js +135 -0
  118. package/lib/chat/components/app-sidebar.js +237 -0
  119. package/lib/chat/components/app-sidebar.jsx +289 -0
  120. package/lib/chat/components/chat-header.js +27 -0
  121. package/lib/chat/components/chat-header.jsx +37 -0
  122. package/lib/chat/components/chat-input.js +230 -0
  123. package/lib/chat/components/chat-input.jsx +228 -0
  124. package/lib/chat/components/chat-nav-context.js +11 -0
  125. package/lib/chat/components/chat-nav-context.jsx +11 -0
  126. package/lib/chat/components/chat-page.js +81 -0
  127. package/lib/chat/components/chat-page.jsx +100 -0
  128. package/lib/chat/components/chat.js +150 -0
  129. package/lib/chat/components/chat.jsx +182 -0
  130. package/lib/chat/components/chats-page.js +302 -0
  131. package/lib/chat/components/chats-page.jsx +330 -0
  132. package/lib/chat/components/crons-page.js +172 -0
  133. package/lib/chat/components/crons-page.jsx +244 -0
  134. package/lib/chat/components/enhanced-tool-call.js +103 -0
  135. package/lib/chat/components/enhanced-tool-call.jsx +139 -0
  136. package/lib/chat/components/findings-page.js +175 -0
  137. package/lib/chat/components/findings-page.jsx +214 -0
  138. package/lib/chat/components/greeting.js +22 -0
  139. package/lib/chat/components/greeting.jsx +26 -0
  140. package/lib/chat/components/icons.js +777 -0
  141. package/lib/chat/components/icons.jsx +741 -0
  142. package/lib/chat/components/index.js +26 -0
  143. package/lib/chat/components/mcp-page.js +260 -0
  144. package/lib/chat/components/mcp-page.jsx +355 -0
  145. package/lib/chat/components/message.js +289 -0
  146. package/lib/chat/components/message.jsx +315 -0
  147. package/lib/chat/components/messages.js +66 -0
  148. package/lib/chat/components/messages.jsx +77 -0
  149. package/lib/chat/components/notifications-page.js +56 -0
  150. package/lib/chat/components/notifications-page.jsx +87 -0
  151. package/lib/chat/components/page-layout.js +21 -0
  152. package/lib/chat/components/page-layout.jsx +28 -0
  153. package/lib/chat/components/registry-page.js +222 -0
  154. package/lib/chat/components/registry-page.jsx +255 -0
  155. package/lib/chat/components/settings-layout.js +40 -0
  156. package/lib/chat/components/settings-layout.jsx +54 -0
  157. package/lib/chat/components/settings-secrets-page.js +216 -0
  158. package/lib/chat/components/settings-secrets-page.jsx +264 -0
  159. package/lib/chat/components/sidebar-history-item.js +132 -0
  160. package/lib/chat/components/sidebar-history-item.jsx +113 -0
  161. package/lib/chat/components/sidebar-history.js +115 -0
  162. package/lib/chat/components/sidebar-history.jsx +157 -0
  163. package/lib/chat/components/sidebar-user-nav.js +63 -0
  164. package/lib/chat/components/sidebar-user-nav.jsx +73 -0
  165. package/lib/chat/components/status-bar.js +39 -0
  166. package/lib/chat/components/status-bar.jsx +51 -0
  167. package/lib/chat/components/swarm-page.js +157 -0
  168. package/lib/chat/components/swarm-page.jsx +210 -0
  169. package/lib/chat/components/targets-page.js +376 -0
  170. package/lib/chat/components/targets-page.jsx +389 -0
  171. package/lib/chat/components/tool-call.js +86 -0
  172. package/lib/chat/components/tool-call.jsx +104 -0
  173. package/lib/chat/components/tool-panel.js +107 -0
  174. package/lib/chat/components/tool-panel.jsx +145 -0
  175. package/lib/chat/components/triggers-page.js +153 -0
  176. package/lib/chat/components/triggers-page.jsx +221 -0
  177. package/lib/chat/components/ui/confirm-dialog.js +53 -0
  178. package/lib/chat/components/ui/confirm-dialog.jsx +57 -0
  179. package/lib/chat/components/ui/dropdown-menu.js +98 -0
  180. package/lib/chat/components/ui/dropdown-menu.jsx +116 -0
  181. package/lib/chat/components/ui/rename-dialog.js +74 -0
  182. package/lib/chat/components/ui/rename-dialog.jsx +72 -0
  183. package/lib/chat/components/ui/scroll-area.js +13 -0
  184. package/lib/chat/components/ui/scroll-area.jsx +17 -0
  185. package/lib/chat/components/ui/separator.js +21 -0
  186. package/lib/chat/components/ui/separator.jsx +18 -0
  187. package/lib/chat/components/ui/sheet.js +75 -0
  188. package/lib/chat/components/ui/sheet.jsx +95 -0
  189. package/lib/chat/components/ui/sidebar.js +227 -0
  190. package/lib/chat/components/ui/sidebar.jsx +245 -0
  191. package/lib/chat/components/ui/tooltip.js +56 -0
  192. package/lib/chat/components/ui/tooltip.jsx +66 -0
  193. package/lib/chat/components/upgrade-dialog.js +151 -0
  194. package/lib/chat/components/upgrade-dialog.jsx +170 -0
  195. package/lib/chat/utils.js +11 -0
  196. package/lib/cron.js +246 -0
  197. package/lib/db/api-keys.js +163 -0
  198. package/lib/db/chats.js +145 -0
  199. package/lib/db/index.js +52 -0
  200. package/lib/db/notifications.js +99 -0
  201. package/lib/db/schema.js +145 -0
  202. package/lib/db/update-check.js +96 -0
  203. package/lib/db/users.js +89 -0
  204. package/lib/mcp/actions.js +104 -0
  205. package/lib/mcp/client.js +79 -0
  206. package/lib/mcp/handler.js +57 -0
  207. package/lib/mcp/server.js +165 -0
  208. package/lib/paths.js +46 -0
  209. package/lib/registry/actions.js +164 -0
  210. package/lib/registry/catalog.js +137 -0
  211. package/lib/registry/tools.js +71 -0
  212. package/lib/tools/create-job.js +99 -0
  213. package/lib/tools/github.js +217 -0
  214. package/lib/tools/openai.js +35 -0
  215. package/lib/tools/telegram.js +292 -0
  216. package/lib/triggers.js +118 -0
  217. package/lib/utils/render-md.js +102 -0
  218. package/package.json +103 -0
  219. package/setup/lib/auth.mjs +81 -0
  220. package/setup/lib/env.mjs +21 -0
  221. package/setup/lib/fs-utils.mjs +20 -0
  222. package/setup/lib/github.mjs +149 -0
  223. package/setup/lib/prerequisites.mjs +155 -0
  224. package/setup/lib/prompts.mjs +267 -0
  225. package/setup/lib/providers.mjs +48 -0
  226. package/setup/lib/sync.mjs +125 -0
  227. package/setup/lib/targets.mjs +45 -0
  228. package/setup/lib/telegram-verify.mjs +63 -0
  229. package/setup/lib/telegram.mjs +76 -0
  230. package/setup/setup-telegram.mjs +264 -0
  231. package/setup/setup.mjs +842 -0
  232. package/templates/.dockerignore +5 -0
  233. package/templates/.env.example +63 -0
  234. package/templates/.github/workflows/auto-merge.yml +117 -0
  235. package/templates/.github/workflows/build-image.yml +36 -0
  236. package/templates/.github/workflows/notify-job-failed.yml +64 -0
  237. package/templates/.github/workflows/notify-pr-complete.yml +119 -0
  238. package/templates/.github/workflows/rebuild-event-handler.yml +121 -0
  239. package/templates/.github/workflows/run-job.yml +89 -0
  240. package/templates/.github/workflows/upgrade-event-handler.yml +62 -0
  241. package/templates/.gitignore.template +45 -0
  242. package/templates/.pi/extensions/env-sanitizer/index.ts +48 -0
  243. package/templates/.pi/extensions/env-sanitizer/package.json +5 -0
  244. package/templates/CLAUDE.md +29 -0
  245. package/templates/CLAUDE.md.template +307 -0
  246. package/templates/app/api/[...thepopebot]/route.js +1 -0
  247. package/templates/app/api/auth/[...nextauth]/route.js +1 -0
  248. package/templates/app/chat/[chatId]/page.js +8 -0
  249. package/templates/app/chats/page.js +7 -0
  250. package/templates/app/components/ascii-logo.jsx +10 -0
  251. package/templates/app/components/login-form.jsx +92 -0
  252. package/templates/app/components/setup-form.jsx +82 -0
  253. package/templates/app/components/theme-provider.jsx +11 -0
  254. package/templates/app/components/theme-toggle.jsx +38 -0
  255. package/templates/app/components/ui/button.jsx +21 -0
  256. package/templates/app/components/ui/card.jsx +23 -0
  257. package/templates/app/components/ui/input.jsx +10 -0
  258. package/templates/app/components/ui/label.jsx +10 -0
  259. package/templates/app/crons/page.js +5 -0
  260. package/templates/app/findings/page.js +7 -0
  261. package/templates/app/globals.css +90 -0
  262. package/templates/app/layout.js +19 -0
  263. package/templates/app/login/page.js +15 -0
  264. package/templates/app/notifications/page.js +7 -0
  265. package/templates/app/page.js +7 -0
  266. package/templates/app/settings/crons/page.js +5 -0
  267. package/templates/app/settings/layout.js +7 -0
  268. package/templates/app/settings/mcp/page.js +5 -0
  269. package/templates/app/settings/page.js +5 -0
  270. package/templates/app/settings/secrets/page.js +5 -0
  271. package/templates/app/settings/triggers/page.js +5 -0
  272. package/templates/app/stream/chat/route.js +1 -0
  273. package/templates/app/swarm/page.js +7 -0
  274. package/templates/app/targets/page.js +7 -0
  275. package/templates/app/toolbox/page.js +7 -0
  276. package/templates/app/triggers/page.js +5 -0
  277. package/templates/config/AGENT.md +34 -0
  278. package/templates/config/CRONS.json +56 -0
  279. package/templates/config/EVENT_HANDLER.md +224 -0
  280. package/templates/config/HEARTBEAT.md +3 -0
  281. package/templates/config/JOB_SUMMARY.md +130 -0
  282. package/templates/config/MCP_SERVERS.json +1 -0
  283. package/templates/config/SKILL_BUILDING_GUIDE.md +90 -0
  284. package/templates/config/SOUL.md +17 -0
  285. package/templates/config/TRIGGERS.json +58 -0
  286. package/templates/docker/event-handler/Dockerfile +20 -0
  287. package/templates/docker/event-handler/ecosystem.config.cjs +8 -0
  288. package/templates/docker/job-claude-code/Dockerfile +34 -0
  289. package/templates/docker/job-claude-code/entrypoint.sh +139 -0
  290. package/templates/docker/job-pi-coding-agent/Dockerfile +44 -0
  291. package/templates/docker/job-pi-coding-agent/entrypoint.sh +163 -0
  292. package/templates/docker-compose.yml +63 -0
  293. package/templates/instrumentation.js +6 -0
  294. package/templates/middleware.js +1 -0
  295. package/templates/next.config.mjs +3 -0
  296. package/templates/postcss.config.mjs +5 -0
  297. package/templates/skills/LICENSE +21 -0
  298. package/templates/skills/README.md +119 -0
  299. package/templates/skills/brave-search/SKILL.md +79 -0
  300. package/templates/skills/brave-search/content.js +86 -0
  301. package/templates/skills/brave-search/package-lock.json +621 -0
  302. package/templates/skills/brave-search/package.json +14 -0
  303. package/templates/skills/brave-search/search.js +199 -0
  304. package/templates/skills/browser-tools/SKILL.md +196 -0
  305. package/templates/skills/browser-tools/browser-content.js +103 -0
  306. package/templates/skills/browser-tools/browser-cookies.js +35 -0
  307. package/templates/skills/browser-tools/browser-eval.js +53 -0
  308. package/templates/skills/browser-tools/browser-hn-scraper.js +108 -0
  309. package/templates/skills/browser-tools/browser-nav.js +44 -0
  310. package/templates/skills/browser-tools/browser-pick.js +162 -0
  311. package/templates/skills/browser-tools/browser-screenshot.js +34 -0
  312. package/templates/skills/browser-tools/browser-start.js +87 -0
  313. package/templates/skills/browser-tools/package-lock.json +2556 -0
  314. package/templates/skills/browser-tools/package.json +19 -0
  315. package/templates/skills/llm-secrets/SKILL.md +34 -0
  316. package/templates/skills/llm-secrets/llm-secrets.js +33 -0
  317. package/templates/skills/modify-self/SKILL.md +12 -0
@@ -0,0 +1,3 @@
1
+ # Heartbeat Tasks
2
+
3
+ Get the local weather for Claremont, CA and put it in /job/WEATHER.txt
@@ -0,0 +1,130 @@
1
+ # Job Summary Bot
2
+
3
+ You convert job result data into concise, scannable summaries. Adjust detail based on outcome: **less detail on success**, **more detail on failure or struggles**.
4
+
5
+ ## Output Rules
6
+
7
+ - On success, lead with a short celebration using the short version of the actual job ID.
8
+ - On failure (status is failure, cancelled, or timed_out), lead with a failure notice.
9
+ - The job description should be a hyperlink to the PR on GitHub (or the run URL if no PR exists).
10
+ - If the status is not closed/merged, prompt the reader to review it, with "Pull Request" as a hyperlink to the PR.
11
+ - List changed files using dashes only (not bullets, **not** a link or clickable), with no explanations next to files.
12
+ - Do not include `/logs` in the file list.
13
+
14
+ ## Output Format
15
+
16
+ ```
17
+ Nice! <short_job_id> completed!
18
+
19
+ Job: <job description as hyperlink to PR>
20
+ Status: <status>
21
+
22
+ Changes:
23
+ - /folder/file1
24
+ - /folder/file2
25
+
26
+ Steps:
27
+ - <what the agent did, chronologically>
28
+
29
+ Went well:
30
+ - <optional — only if something notable>
31
+
32
+ Struggled with:
33
+ - <optional — only if the agent hit difficulties>
34
+ ```
35
+
36
+ ### Section Rules
37
+
38
+ **Steps** (always shown):
39
+ - Up to 10 bullet points, fewer is fine — only include meaningful steps
40
+ - Chronological order of what the agent actually did
41
+ - Brief, action-oriented language (e.g., "Updated login flow", "Fixed 2 failing tests")
42
+ - Skip trivial steps like reading files, thinking, or navigating — focus on actions taken
43
+
44
+ **Went well** (optional — omit entirely if nothing notable):
45
+ - 1-3 brief bullets on what worked smoothly or was done cleverly
46
+ - Only include when there's something genuinely worth calling out
47
+
48
+ **Struggled with** (optional — omit entirely if clean run):
49
+ - 1-3 brief bullets on difficulties, retries, or workarounds
50
+ - More detail on failure, less on success
51
+
52
+ ## Examples
53
+
54
+ Successful run:
55
+
56
+ Nice! a1b2c3d completed!
57
+
58
+ Job: [Update auth module](https://github.com/org/repo/pull/42)
59
+ Status: ✅ Merged
60
+
61
+ Changes:
62
+ - /src/auth/login.ts
63
+ - /src/auth/utils.ts
64
+
65
+ Steps:
66
+ - Analyzed the existing auth module structure
67
+ - Created new OAuth provider config
68
+ - Updated login flow to use new provider
69
+ - Ran tests and fixed 2 failing assertions
70
+ - Cleaned up unused imports
71
+
72
+
73
+ Open PR needing review:
74
+
75
+ Nice! a1b2c3d completed!
76
+
77
+ Job: [Fix pagination bug](https://github.com/org/repo/pull/43)
78
+ Status: ⏳ Open — please review the [Pull Request](https://github.com/org/repo/pull/43)
79
+
80
+ Changes:
81
+ - /src/components/table.tsx
82
+
83
+ Steps:
84
+ - Identified off-by-one error in pagination logic
85
+ - Patched the index calculation
86
+ - Verified fix against edge cases
87
+
88
+
89
+ Run with struggles:
90
+
91
+ Nice! a1b2c3d completed!
92
+
93
+ Job: [Add PDF export](https://github.com/org/repo/pull/44)
94
+ Status: ✅ Merged
95
+
96
+ Changes:
97
+ - /src/export/pdf.ts
98
+ - /package.json
99
+
100
+ Steps:
101
+ - Researched PDF generation libraries
102
+ - Attempted jsPDF but hit rendering issues
103
+ - Switched to puppeteer-based approach
104
+ - Installed dependencies and configured headless Chrome
105
+ - Implemented PDF export endpoint
106
+ - Added tests
107
+
108
+ Went well:
109
+ - Final puppeteer implementation produces clean, well-formatted PDFs
110
+
111
+ Struggled with:
112
+ - Took several attempts to find a library that worked in the container environment
113
+
114
+
115
+ Failed run (no PR):
116
+
117
+ Job a1b2c3d failed!
118
+
119
+ Job: [Add PDF export](https://github.com/org/repo/runs/12345)
120
+ Status: ❌ Failed
121
+
122
+ Steps:
123
+ - Cloned repo and analyzed task requirements
124
+ - Started implementing PDF export
125
+ - Hit dependency installation errors
126
+ - Attempted 3 different libraries without success
127
+
128
+ Struggled with:
129
+ - Could not resolve puppeteer dependencies in the container environment
130
+ - Ran out of retries after 3 failed installation attempts
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1,90 @@
1
+ # Skill Building Guide
2
+
3
+ ## What is a skill?
4
+
5
+ Skills are lightweight wrappers that extend agent abilities. They live in `skills/<skill-name>/` and are activated by symlinking into `skills/active/`. Both Pi and Claude Code discover skills from the same shared directory.
6
+
7
+ ## Skill structure
8
+
9
+ - **`SKILL.md`** (required) — YAML frontmatter + markdown documentation
10
+ - **Scripts** (optional) — prefer bash (.sh) for simplicity
11
+ - **`package.json`** (optional) — only if Node.js dependencies are truly needed
12
+
13
+ ## SKILL.md format
14
+
15
+ The `description` from frontmatter appears in the system prompt under "Active skills."
16
+ Use project-root-relative paths in documentation (e.g., `skills/<skill-name>/script.sh`).
17
+
18
+ ```
19
+ ---
20
+ name: skill-name-in-kebab-case
21
+ description: One sentence describing what the skill does and when to use it.
22
+ ---
23
+
24
+ # Skill Name
25
+
26
+ ## Usage
27
+
28
+ ```bash
29
+ skills/skill-name/script.sh <args>
30
+ ```
31
+ ```
32
+
33
+ ## Example: Simple bash skill (most common pattern)
34
+
35
+ The built-in `transcribe` skill — a SKILL.md and a single bash script:
36
+
37
+ **skills/transcribe/SKILL.md:**
38
+ ```
39
+ ---
40
+ name: transcribe
41
+ description: Speech-to-text transcription using Groq Whisper API. Supports m4a, mp3, wav, ogg, flac, webm.
42
+ ---
43
+
44
+ # Transcribe
45
+
46
+ Speech-to-text using Groq Whisper API.
47
+
48
+ ## Setup
49
+ Requires GROQ_API_KEY environment variable.
50
+
51
+ ## Usage
52
+ ```bash
53
+ skills/transcribe/transcribe.sh <audio-file>
54
+ ```
55
+ ```
56
+
57
+ **skills/transcribe/transcribe.sh:**
58
+ ```bash
59
+ #!/bin/bash
60
+ if [ -z "$1" ]; then echo "Usage: transcribe.sh <audio-file>"; exit 1; fi
61
+ if [ -z "$GROQ_API_KEY" ]; then echo "Error: GROQ_API_KEY not set"; exit 1; fi
62
+ curl -s -X POST "https://api.groq.com/openai/v1/audio/transcriptions" \
63
+ -H "Authorization: Bearer $GROQ_API_KEY" \
64
+ -F "file=@${1}" \
65
+ -F "model=whisper-large-v3-turbo" \
66
+ -F "response_format=text"
67
+ ```
68
+
69
+ ## Example: Skill with Node.js dependencies
70
+
71
+ The built-in `brave-search` skill uses Node.js for HTML parsing (jsdom, readability, turndown). It has a `package.json` and `.js` scripts. Dependencies are installed automatically in Docker. Use this pattern only when bash + curl isn't sufficient.
72
+
73
+ ## Activation
74
+
75
+ After creating skill files, symlink to activate:
76
+ ```bash
77
+ ln -s ../skill-name skills/active/skill-name
78
+ ```
79
+
80
+ ## Always build AND test in the same job
81
+
82
+ Tell the agent to test the skill with real input after creating it and fix any issues before committing. Don't create untested skills.
83
+
84
+ ## Credential setup
85
+
86
+ If a skill needs an API key, the user should set it up BEFORE the job runs:
87
+ - `npx thepopebot set-agent-llm-secret <KEY_NAME> <value>` — creates a GitHub secret with `AGENT_LLM_` prefix, exposed as an env var in the Docker container
88
+ - The value is stored exactly as provided, no transformation needed
89
+ - Also add to `.env` for local development
90
+ - Keys can be rotated later with the same command
@@ -0,0 +1,17 @@
1
+ # thepopebot Soul
2
+
3
+ ## Identity
4
+
5
+ You are a diligent and capable AI worker. You approach tasks with focus, patience, and craftsmanship.
6
+
7
+ ## Personality Traits
8
+
9
+ - **Methodical**: You work through problems systematically, step by step
10
+ - **Reliable**: You follow through on commitments and complete what I start
11
+ - **Curious**: You explore and learn from the codebase I work with
12
+ - **Working Style**: You prefer to plan before acting
13
+
14
+ ## Values
15
+
16
+ - **Quality over speed**: Better to do it right than do it twice
17
+ - **Simplicity**: The simplest solution that works is usually best
@@ -0,0 +1,58 @@
1
+ [
2
+ {
3
+ "name": "on-github-event",
4
+ "watch_path": "/github/webhook",
5
+ "actions": [
6
+ { "type": "command", "command": "echo 'github webhook fired'" }
7
+ ],
8
+ "enabled": false
9
+ },
10
+ {
11
+ "name": "on-webhook-log",
12
+ "watch_path": "/webhook",
13
+ "actions": [
14
+ { "type": "command", "command": "echo 'webhook received: {{body}}'" }
15
+ ],
16
+ "enabled": false
17
+ },
18
+ {
19
+ "name": "review-github-event",
20
+ "watch_path": "/github/webhook",
21
+ "actions": [
22
+ { "type": "agent", "job": "A GitHub event occurred. Review the payload and summarize what happened:\n{{body}}" }
23
+ ],
24
+ "enabled": false
25
+ },
26
+ {
27
+ "name": "react-to-webhook",
28
+ "watch_path": "/webhook",
29
+ "actions": [
30
+ { "type": "agent", "job": "A webhook was received. Analyze the payload and decide if any action is needed:\n{{body}}" }
31
+ ],
32
+ "enabled": false
33
+ },
34
+ {
35
+ "name": "forward-github",
36
+ "watch_path": "/github/webhook",
37
+ "actions": [
38
+ { "type": "webhook", "url": "https://example.com/hook", "method": "POST", "vars": { "source": "github" } }
39
+ ],
40
+ "enabled": false
41
+ },
42
+ {
43
+ "name": "forward-webhook",
44
+ "watch_path": "/webhook",
45
+ "actions": [
46
+ { "type": "webhook", "url": "https://example.com/hook", "method": "POST", "vars": { "source": "webhook" } }
47
+ ],
48
+ "enabled": false
49
+ },
50
+ {
51
+ "name": "review-with-openai",
52
+ "watch_path": "/github/webhook",
53
+ "actions": [
54
+ { "type": "agent", "job": "Review the GitHub event and summarize what happened:\n{{body}}", "llm_provider": "openai", "llm_model": "gpt-4o" }
55
+ ],
56
+ "enabled": false
57
+ }
58
+ ]
@@ -0,0 +1,20 @@
1
+ FROM node:22-bookworm-slim
2
+
3
+ RUN apt-get update && apt-get install -y curl git python3 make g++ && \
4
+ curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
5
+ | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && \
6
+ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
7
+ | tee /etc/apt/sources.list.d/github-cli.list > /dev/null && \
8
+ apt-get update && apt-get install -y gh && \
9
+ rm -rf /var/lib/apt/lists/*
10
+ RUN npm install -g pm2
11
+
12
+ WORKDIR /app
13
+ COPY package.json package-lock.json* ./
14
+ RUN npm install --omit=dev && \
15
+ npm install --no-save thepopebot@$(node -p "require('./package.json').version")
16
+
17
+ COPY /templates/docker/event-handler/ecosystem.config.cjs /opt/ecosystem.config.cjs
18
+
19
+ EXPOSE 80
20
+ CMD ["pm2-runtime", "/opt/ecosystem.config.cjs"]
@@ -0,0 +1,8 @@
1
+ module.exports = {
2
+ apps: [{
3
+ name: 'next',
4
+ script: 'node_modules/.bin/next',
5
+ args: 'start -p 80',
6
+ kill_timeout: 120000,
7
+ }]
8
+ };
@@ -0,0 +1,34 @@
1
+ FROM node:22-bookworm-slim
2
+
3
+ RUN apt-get update && apt-get install -y \
4
+ git \
5
+ jq \
6
+ curl \
7
+ procps \
8
+ libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 \
9
+ libcups2 libdrm2 libdbus-1-3 libxkbcommon0 \
10
+ libatspi2.0-0 libxcomposite1 libxdamage1 libxfixes3 \
11
+ libxrandr2 libgbm1 libasound2 libpango-1.0-0 libcairo2 \
12
+ && rm -rf /var/lib/apt/lists/*
13
+
14
+ # Install GitHub CLI
15
+ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
16
+ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
17
+ && apt-get update && apt-get install -y gh \
18
+ && rm -rf /var/lib/apt/lists/*
19
+
20
+ RUN npm install -g @anthropic-ai/claude-code
21
+
22
+ # Claude Code refuses --dangerously-skip-permissions as root.
23
+ # Create a non-root user and give it ownership of /job.
24
+ RUN useradd -m -s /bin/bash agent \
25
+ && mkdir -p /job \
26
+ && chown agent:agent /job
27
+
28
+ COPY entrypoint.sh /entrypoint.sh
29
+ RUN chmod +x /entrypoint.sh
30
+
31
+ USER agent
32
+ WORKDIR /job
33
+
34
+ ENTRYPOINT ["/entrypoint.sh"]
@@ -0,0 +1,139 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Extract job ID from branch name (job/uuid -> uuid), fallback to random UUID
5
+ if [[ "$BRANCH" == job/* ]]; then
6
+ JOB_ID="${BRANCH#job/}"
7
+ else
8
+ JOB_ID=$(cat /proc/sys/kernel/random/uuid)
9
+ fi
10
+ echo "Job ID: ${JOB_ID}"
11
+
12
+ # Export SECRETS (JSON) as flat env vars (GH_TOKEN, CLAUDE_CODE_OAUTH_TOKEN, etc.)
13
+ if [ -n "$SECRETS" ]; then
14
+ eval $(echo "$SECRETS" | jq -r 'to_entries | .[] | "export \(.key)=\(.value | @sh)"')
15
+ fi
16
+
17
+ # Export LLM_SECRETS (JSON) as flat env vars
18
+ if [ -n "$LLM_SECRETS" ]; then
19
+ eval $(echo "$LLM_SECRETS" | jq -r 'to_entries | .[] | "export \(.key)=\(.value | @sh)"')
20
+ fi
21
+
22
+ # Unset ANTHROPIC_API_KEY so Claude Code uses the OAuth token.
23
+ # If both are set, Claude Code prioritizes API key (billing to API credits)
24
+ # which defeats the purpose. The API key is for the event handler, not here.
25
+ unset ANTHROPIC_API_KEY
26
+
27
+ # Git setup - derive identity from GitHub token
28
+ gh auth setup-git
29
+ GH_USER_JSON=$(gh api user -q '{name: .name, login: .login, email: .email, id: .id}')
30
+ GH_USER_NAME=$(echo "$GH_USER_JSON" | jq -r '.name // .login')
31
+ GH_USER_EMAIL=$(echo "$GH_USER_JSON" | jq -r '.email // "\(.id)+\(.login)@users.noreply.github.com"')
32
+ git config --global user.name "$GH_USER_NAME"
33
+ git config --global user.email "$GH_USER_EMAIL"
34
+
35
+ # Clone branch
36
+ if [ -n "$REPO_URL" ]; then
37
+ git clone --single-branch --branch "$BRANCH" --depth 1 "$REPO_URL" /job
38
+ else
39
+ echo "No REPO_URL provided"
40
+ fi
41
+
42
+ cd /job
43
+
44
+ # Install npm deps for active skills (native deps need correct Linux arch)
45
+ for skill_dir in /job/skills/active/*/; do
46
+ if [ -f "${skill_dir}package.json" ]; then
47
+ echo "Installing skill deps: $(basename "$skill_dir")"
48
+ (cd "$skill_dir" && npm install --omit=dev --no-package-lock)
49
+ fi
50
+ done
51
+
52
+ # Start Chrome if puppeteer installed it (needed by browser-tools skill)
53
+ CHROME_PID=""
54
+ CHROME_BIN=$(find /home/agent/.cache/puppeteer -name "chrome" -type f 2>/dev/null | head -1)
55
+ if [ -n "$CHROME_BIN" ]; then
56
+ $CHROME_BIN --headless --no-sandbox --disable-gpu --remote-debugging-port=9222 2>/dev/null &
57
+ CHROME_PID=$!
58
+ sleep 2
59
+ fi
60
+
61
+ # Setup logs
62
+ LOG_DIR="/job/logs/${JOB_ID}"
63
+ mkdir -p "${LOG_DIR}"
64
+
65
+ # Build system prompt from config MD files
66
+ SYSTEM_PROMPT_FILE="${LOG_DIR}/system-prompt.md"
67
+ SYSTEM_FILES=("SOUL.md" "AGENT.md")
68
+ > "$SYSTEM_PROMPT_FILE"
69
+ for i in "${!SYSTEM_FILES[@]}"; do
70
+ cat "/job/config/${SYSTEM_FILES[$i]}" >> "$SYSTEM_PROMPT_FILE"
71
+ if [ "$i" -lt $((${#SYSTEM_FILES[@]} - 1)) ]; then
72
+ echo -e "\n\n" >> "$SYSTEM_PROMPT_FILE"
73
+ fi
74
+ done
75
+
76
+ # Resolve {{datetime}} variable in system prompt
77
+ sed -i "s/{{datetime}}/$(date -u +"%Y-%m-%dT%H:%M:%SZ")/g" "$SYSTEM_PROMPT_FILE"
78
+
79
+ # Read job metadata from job.config.json
80
+ JOB_CONFIG="/job/logs/${JOB_ID}/job.config.json"
81
+ TITLE=$(jq -r '.title // empty' "$JOB_CONFIG")
82
+ JOB_DESCRIPTION=$(jq -r '.job // empty' "$JOB_CONFIG")
83
+
84
+ PROMPT="
85
+
86
+ # Your Job
87
+
88
+ ${JOB_DESCRIPTION}"
89
+
90
+ # Build --model flag if LLM_MODEL is set
91
+ MODEL_FLAG=""
92
+ if [ -n "$LLM_MODEL" ]; then
93
+ MODEL_FLAG="--model $LLM_MODEL"
94
+ fi
95
+
96
+ # Run Claude Code — capture exit code instead of letting set -e kill the script
97
+ # stream-json gives the full conversation trace (thinking, tool calls, results)
98
+ # similar to Pi's .jsonl session logs
99
+ set +e
100
+ claude -p "$PROMPT" \
101
+ $MODEL_FLAG \
102
+ --append-system-prompt-file "$SYSTEM_PROMPT_FILE" \
103
+ --dangerously-skip-permissions \
104
+ --verbose \
105
+ --output-format stream-json \
106
+ > "${LOG_DIR}/claude-session.jsonl" 2>"${LOG_DIR}/claude-stderr.log"
107
+ AGENT_EXIT=$?
108
+
109
+ # Commit based on outcome
110
+ if [ $AGENT_EXIT -ne 0 ]; then
111
+ # Claude Code failed — only commit session logs, not partial code changes
112
+ git reset || true
113
+ git add -f "${LOG_DIR}"
114
+ git commit -m "🤖 Agent Job: ${TITLE} (failed)" || true
115
+ else
116
+ # Claude Code succeeded — commit everything
117
+ git add -A
118
+ git add -f "${LOG_DIR}"
119
+ git commit -m "🤖 Agent Job: ${TITLE}" || true
120
+ fi
121
+
122
+ git push origin
123
+ set -e
124
+
125
+ # Cleanup Chrome
126
+ if [ -n "$CHROME_PID" ]; then
127
+ kill $CHROME_PID 2>/dev/null || true
128
+ fi
129
+
130
+ # Create PR (auto-merge handled by GitHub Actions workflow)
131
+ gh pr create --title "🤖 Agent Job: ${TITLE}" --body "${JOB_DESCRIPTION}" --base main || true
132
+
133
+ # Re-raise failure so the workflow reports it
134
+ if [ $AGENT_EXIT -ne 0 ]; then
135
+ echo "Claude Code exited with code ${AGENT_EXIT}"
136
+ exit $AGENT_EXIT
137
+ fi
138
+
139
+ echo "Done. Job ID: ${JOB_ID}"
@@ -0,0 +1,44 @@
1
+ FROM node:22-bookworm-slim
2
+
3
+ RUN apt-get update && apt-get install -y \
4
+ git \
5
+ jq \
6
+ curl \
7
+ procps \
8
+ # Chrome/Chromium dependencies
9
+ libnss3 \
10
+ libnspr4 \
11
+ libatk1.0-0 \
12
+ libatk-bridge2.0-0 \
13
+ libcups2 \
14
+ libdrm2 \
15
+ libdbus-1-3 \
16
+ libxkbcommon0 \
17
+ libatspi2.0-0 \
18
+ libxcomposite1 \
19
+ libxdamage1 \
20
+ libxfixes3 \
21
+ libxrandr2 \
22
+ libgbm1 \
23
+ libasound2 \
24
+ libpango-1.0-0 \
25
+ libcairo2 \
26
+ && rm -rf /var/lib/apt/lists/*
27
+
28
+ # Install GitHub CLI
29
+ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
30
+ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
31
+ && apt-get update && apt-get install -y gh \
32
+ && rm -rf /var/lib/apt/lists/*
33
+
34
+ RUN npm install -g @mariozechner/pi-coding-agent
35
+
36
+ # Create Pi config directory (extension loaded from repo at runtime)
37
+ RUN mkdir -p /root/.pi/agent
38
+
39
+ COPY entrypoint.sh /entrypoint.sh
40
+ RUN chmod +x /entrypoint.sh
41
+
42
+ WORKDIR /job
43
+
44
+ ENTRYPOINT ["/entrypoint.sh"]