claude-beacon 1.0.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -19
- package/config.example.yaml +52 -15
- package/dist/index.js +153 -142
- package/dist/mux.js +122 -111
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -150,6 +150,7 @@ Create or edit `~/.mcp.json` (all projects) or `.mcp.json` in your project root.
|
|
|
150
150
|
"mcpServers": {
|
|
151
151
|
"claude-beacon": {
|
|
152
152
|
"command": "/home/you/.bun/bin/claude-beacon",
|
|
153
|
+
"args": ["--author", "YourGitHubUsername"],
|
|
153
154
|
"env": {
|
|
154
155
|
"GITHUB_WEBHOOK_SECRET": "your-secret-from-step-2",
|
|
155
156
|
"GITHUB_TOKEN": "your-pat"
|
|
@@ -161,6 +162,8 @@ Create or edit `~/.mcp.json` (all projects) or `.mcp.json` in your project root.
|
|
|
161
162
|
|
|
162
163
|
Replace `/home/you` with your home directory (`echo $HOME`). Bun installs globals to `~/.bun/bin/`.
|
|
163
164
|
|
|
165
|
+
`--author` can be repeated for multiple entries and accepts both GitHub usernames and email addresses (see [`allowed_authors`](#webhook-filters)). It is equivalent to setting `webhooks.allowed_authors` in a config file — use whichever is more convenient.
|
|
166
|
+
|
|
164
167
|
**If you cloned the repo** (or prefer `bunx` for always-latest):
|
|
165
168
|
|
|
166
169
|
```json
|
|
@@ -168,7 +171,7 @@ Replace `/home/you` with your home directory (`echo $HOME`). Bun installs global
|
|
|
168
171
|
"mcpServers": {
|
|
169
172
|
"claude-beacon": {
|
|
170
173
|
"command": "/home/you/.bun/bin/bunx",
|
|
171
|
-
"args": ["claude-beacon"],
|
|
174
|
+
"args": ["claude-beacon", "--author", "YourGitHubUsername"],
|
|
172
175
|
"env": {
|
|
173
176
|
"GITHUB_WEBHOOK_SECRET": "your-secret-from-step-2",
|
|
174
177
|
"GITHUB_TOKEN": "your-pat"
|
|
@@ -373,9 +376,28 @@ Environment variables (`WEBHOOK_PORT`, `GITHUB_WEBHOOK_SECRET`, `GITHUB_TOKEN`)
|
|
|
373
376
|
|
|
374
377
|
| Key | Type | Default | Description |
|
|
375
378
|
|---|---|---|---|
|
|
379
|
+
| `webhooks.allowed_authors` | string[] | **required** | GitHub usernames and/or emails whose PRs trigger actions. See below. |
|
|
376
380
|
| `webhooks.allowed_events` | string[] | `[]` (all) | Allowlist of GitHub event types to process. Empty = accept all supported types |
|
|
377
381
|
| `webhooks.allowed_repos` | string[] | `[]` (all) | Allowlist of repos as `"owner/repo"`. Empty = accept all |
|
|
378
382
|
|
|
383
|
+
**`allowed_authors` — required field**
|
|
384
|
+
|
|
385
|
+
claude-beacon will refuse to start if this list is empty. It prevents the agent from rebasing or reviewing your colleagues' PRs.
|
|
386
|
+
|
|
387
|
+
Two kinds of entries:
|
|
388
|
+
|
|
389
|
+
- **Username** (no `@`) — matched against `pr.user.login`, the PR author's GitHub handle.
|
|
390
|
+
- **Email** (contains `@`) — matched against `Co-Authored-By` commit trailers. Use this when an AI agent like Devin creates the PR on your behalf: your email appears in the commit even though the bot is the PR author. The co-author lookup makes an extra API call per PR and requires `GITHUB_TOKEN`.
|
|
391
|
+
|
|
392
|
+
```yaml
|
|
393
|
+
webhooks:
|
|
394
|
+
allowed_authors:
|
|
395
|
+
- Matovidlo # your GitHub username
|
|
396
|
+
- martin@company.com # your email, for Devin / AI-agent co-authored PRs
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
> **Review events** (PR review comments, inline comments) are filtered by username only — no co-author API call — to keep latency low. If a bot creates the PR, add the bot's GitHub login (e.g. `devin-ai-integration[bot]`) as an additional username entry to cover review events for those PRs.
|
|
400
|
+
|
|
379
401
|
Supported event type strings: `push`, `workflow_run`, `workflow_job`, `check_suite`, `pull_request`, `pull_request_review`, `pull_request_review_comment`, `pull_request_review_thread`, `issue_comment`.
|
|
380
402
|
|
|
381
403
|
### Behavior — agent instructions
|
|
@@ -386,9 +408,18 @@ These control what Claude is asked to do when an event fires. Each field accepts
|
|
|
386
408
|
|---|---|---|
|
|
387
409
|
| `behavior.on_ci_failure_main.instruction` | `workflow_run` failure on a main branch | — |
|
|
388
410
|
| `behavior.on_ci_failure_branch.instruction` | `workflow_run` failure on any other branch | — |
|
|
389
|
-
| `behavior.on_pr_review.instruction` | PR review / comment events (after debounce) | `require_plan`, `skill` |
|
|
411
|
+
| `behavior.on_pr_review.instruction` | PR review / comment events (after debounce) | `require_plan`, `skill`, `use_worktree` |
|
|
390
412
|
| `behavior.on_merge_conflict.instruction` | PR with `mergeable_state: dirty` | — |
|
|
391
413
|
| `behavior.on_branch_behind.instruction` | PR with `mergeable_state: behind` | — |
|
|
414
|
+
| `behavior.code_style` | any PR review event | — |
|
|
415
|
+
|
|
416
|
+
`code_style` is a free-form string prepended to every PR review notification. Describe your project's coding conventions here so Claude applies them consistently when addressing comments.
|
|
417
|
+
|
|
418
|
+
**`behavior.worktrees`** — controls how subagents handle rebase and PR review work:
|
|
419
|
+
|
|
420
|
+
| Key | Type | Default | Description |
|
|
421
|
+
|---|---|---|---|
|
|
422
|
+
| `behavior.worktrees.mode` | `"temp"` \| `"native"` | `"temp"` | `temp`: classic `git worktree add/remove` shell commands. `native`: Claude Code's Agent tool `isolation="worktree"` — Claude manages worktree lifecycle automatically. Use `native` if you work in Claude Code native worktrees. |
|
|
392
423
|
|
|
393
424
|
**`on_pr_review` sub-fields:**
|
|
394
425
|
|
|
@@ -396,29 +427,41 @@ These control what Claude is asked to do when an event fires. Each field accepts
|
|
|
396
427
|
|---|---|---|---|
|
|
397
428
|
| `behavior.on_pr_review.require_plan` | boolean | `true` | Whether Claude must enter plan mode before touching code |
|
|
398
429
|
| `behavior.on_pr_review.skill` | string | `"pr-comment-response"` | Skill name invoked to handle the review |
|
|
430
|
+
| `behavior.on_pr_review.use_worktree` | boolean | `false` | When `true`, the PR review subagent runs inside a native Claude Code worktree (`isolation="worktree"`) instead of the current session directory |
|
|
399
431
|
|
|
400
|
-
|
|
432
|
+
### Template placeholders
|
|
401
433
|
|
|
402
|
-
|
|
403
|
-
behavior:
|
|
404
|
-
code_style: |
|
|
405
|
-
- Use TypeScript strict mode; never cast to `any`
|
|
406
|
-
- Prefer `const` over `let`; avoid mutation
|
|
407
|
-
```
|
|
434
|
+
The following placeholders are replaced at runtime inside `instruction` strings. Which placeholders are available depends on the hook:
|
|
408
435
|
|
|
409
|
-
|
|
436
|
+
**CI failure hooks** (`on_ci_failure_main`, `on_ci_failure_branch`):
|
|
410
437
|
|
|
411
|
-
|
|
438
|
+
| Placeholder | Value |
|
|
439
|
+
|---|---|
|
|
440
|
+
| `{repo}` | `owner/repo` |
|
|
441
|
+
| `{branch}` | Branch the workflow ran on |
|
|
442
|
+
| `{run_url}` | Full URL of the GitHub Actions run |
|
|
443
|
+
| `{workflow}` | Workflow name |
|
|
444
|
+
| `{status}` | Conclusion (`failure`) |
|
|
445
|
+
| `{commit}` | First line of the head commit message |
|
|
412
446
|
|
|
413
|
-
|
|
447
|
+
**PR state hooks** (`on_merge_conflict`, `on_branch_behind`):
|
|
414
448
|
|
|
415
449
|
| Placeholder | Value |
|
|
416
450
|
|---|---|
|
|
417
451
|
| `{repo}` | `owner/repo` |
|
|
418
|
-
| `{branch}` | Branch name |
|
|
419
452
|
| `{pr_number}` | Pull request number |
|
|
420
|
-
| `{
|
|
421
|
-
| `{
|
|
453
|
+
| `{pr_title}` | PR title (sanitized) |
|
|
454
|
+
| `{pr_url}` | PR URL |
|
|
455
|
+
| `{head_branch}` | PR head branch |
|
|
456
|
+
| `{base_branch}` | PR base branch |
|
|
457
|
+
| `{worktree_steps}` | Auto-generated rebase steps based on `behavior.worktrees.mode` |
|
|
458
|
+
|
|
459
|
+
**PR review hook** (`on_pr_review`):
|
|
460
|
+
|
|
461
|
+
| Placeholder | Value |
|
|
462
|
+
|---|---|
|
|
463
|
+
| `{skill}` | Value of `behavior.on_pr_review.skill` |
|
|
464
|
+
| `{worktree_preamble}` | Empty when `use_worktree: false`; a context sentence when `true` |
|
|
422
465
|
|
|
423
466
|
### Minimal example
|
|
424
467
|
|
|
@@ -428,13 +471,15 @@ server:
|
|
|
428
471
|
main_branches: [main, release]
|
|
429
472
|
|
|
430
473
|
webhooks:
|
|
474
|
+
allowed_authors:
|
|
475
|
+
- YourGitHubUsername
|
|
431
476
|
allowed_repos:
|
|
432
477
|
- my-org/my-repo # only watch this repo
|
|
433
478
|
|
|
434
479
|
behavior:
|
|
435
480
|
code_style: |
|
|
436
|
-
-
|
|
437
|
-
-
|
|
481
|
+
- Use TypeScript strict mode; never cast to `any`
|
|
482
|
+
- Run linter before committing
|
|
438
483
|
on_pr_review:
|
|
439
484
|
require_plan: true
|
|
440
485
|
skill: pr-comment-response
|
|
@@ -534,7 +579,7 @@ Cloudflared free tier gives a new random URL on each restart. Update it: Repo
|
|
|
534
579
|
## Development
|
|
535
580
|
|
|
536
581
|
```bash
|
|
537
|
-
bun test #
|
|
582
|
+
bun test # run the test suite
|
|
538
583
|
bun run typecheck # tsc --noEmit (strict + noUncheckedIndexedAccess)
|
|
539
584
|
bun run lint # Biome v2
|
|
540
585
|
bun run lint:fix # Auto-fix lint issues
|
|
@@ -555,4 +600,4 @@ Biome v2 is configured in `biome.json` with strict rules. One deliberate deviati
|
|
|
555
600
|
- `.env` is gitignored — secrets stay local
|
|
556
601
|
- `GITHUB_WEBHOOK_SECRET` is **required** — omitting it causes all requests to be rejected; set `WEBHOOK_DEV_MODE=true` to bypass verification in local dev only
|
|
557
602
|
|
|
558
|
-
See [AGENTS.md](AGENTS.md) for the
|
|
603
|
+
See [AGENTS.md](AGENTS.md) for the architecture reference and contributor guide.
|
package/config.example.yaml
CHANGED
|
@@ -33,6 +33,23 @@ server:
|
|
|
33
33
|
|
|
34
34
|
# ── Webhook filters ───────────────────────────────────────────────────────────
|
|
35
35
|
webhooks:
|
|
36
|
+
# REQUIRED — claude-beacon will not start without at least one entry.
|
|
37
|
+
#
|
|
38
|
+
# Controls whose PRs trigger automatic actions (rebase, review response, etc.).
|
|
39
|
+
# Two kinds of entries:
|
|
40
|
+
#
|
|
41
|
+
# username (no "@") — matched against the PR author's GitHub login.
|
|
42
|
+
# email (with "@") — matched against Co-Authored-By commit headers.
|
|
43
|
+
# Use this when a bot (e.g. Devin) authors the PR on your behalf;
|
|
44
|
+
# your email appears in the commit trailer even though the bot is
|
|
45
|
+
# listed as the PR author.
|
|
46
|
+
#
|
|
47
|
+
# Claude will only act on PRs where the author login OR a commit co-author
|
|
48
|
+
# email matches an entry in this list.
|
|
49
|
+
allowed_authors:
|
|
50
|
+
- YourGitHubUsername
|
|
51
|
+
# - you@company.com # uncomment if you use Devin or a similar AI coding agent
|
|
52
|
+
|
|
36
53
|
# Allowlist of GitHub event types to process.
|
|
37
54
|
# Empty list (default) means all supported events are processed.
|
|
38
55
|
# Useful for narrowing a shared webhook to only the events you care about.
|
|
@@ -60,6 +77,23 @@ webhooks:
|
|
|
60
77
|
# by using names that don't appear in the variable list for that event.
|
|
61
78
|
behavior:
|
|
62
79
|
|
|
80
|
+
# ── Worktree mode ────────────────────────────────────────────────────────────
|
|
81
|
+
# Controls how subagents handle rebase / conflict resolution and PR review work.
|
|
82
|
+
#
|
|
83
|
+
# mode: temp (default)
|
|
84
|
+
# Subagents use classic shell commands:
|
|
85
|
+
# git worktree add /tmp/pr-<N>-rebase <branch>
|
|
86
|
+
# ... do work ...
|
|
87
|
+
# git worktree remove /tmp/pr-<N>-rebase
|
|
88
|
+
#
|
|
89
|
+
# mode: native
|
|
90
|
+
# Subagents are spawned via Claude Code's Agent tool with isolation="worktree".
|
|
91
|
+
# Claude manages the worktree lifecycle automatically — no add/remove commands.
|
|
92
|
+
# Use this if you normally work inside Claude Code native worktrees.
|
|
93
|
+
worktrees:
|
|
94
|
+
mode: temp
|
|
95
|
+
# mode: native ← uncomment if you use Claude Code native worktrees
|
|
96
|
+
|
|
63
97
|
# Triggered when a workflow_run fails on a main/master branch.
|
|
64
98
|
# Placeholders: {repo}, {branch}, {run_url}, {workflow}, {status}, {commit}
|
|
65
99
|
on_ci_failure_main:
|
|
@@ -85,7 +119,9 @@ behavior:
|
|
|
85
119
|
3. Push the fix to the branch.
|
|
86
120
|
|
|
87
121
|
# Triggered when a PR review, inline comment, or unresolved thread arrives.
|
|
88
|
-
#
|
|
122
|
+
# Placeholders in instruction: {skill}, {worktree_preamble}
|
|
123
|
+
# {skill} — replaced with the skill field below
|
|
124
|
+
# {worktree_preamble} — injected automatically based on use_worktree (see below)
|
|
89
125
|
on_pr_review:
|
|
90
126
|
# When true, the instruction must direct the agent to enter plan mode
|
|
91
127
|
# before making any code changes. Strongly recommended.
|
|
@@ -94,8 +130,13 @@ behavior:
|
|
|
94
130
|
# Skill invoked during the execution phase.
|
|
95
131
|
skill: pr-comment-response
|
|
96
132
|
|
|
133
|
+
# When true, the PR review work runs as a subagent inside a native Claude Code
|
|
134
|
+
# worktree (Agent tool with isolation="worktree"). Set to true if you normally
|
|
135
|
+
# work in Claude Code native worktrees so reviews apply to an isolated copy.
|
|
136
|
+
use_worktree: false
|
|
137
|
+
|
|
97
138
|
instruction: |
|
|
98
|
-
MANDATORY: Enter plan mode first.
|
|
139
|
+
{worktree_preamble}MANDATORY: Enter plan mode first.
|
|
99
140
|
1. Read every linked thread and summarise what each one asks for
|
|
100
141
|
2. Draft a plan listing the file + change for each thread
|
|
101
142
|
3. Only after the plan is complete, use the {skill} skill to execute
|
|
@@ -104,37 +145,33 @@ behavior:
|
|
|
104
145
|
|
|
105
146
|
Execution phase:
|
|
106
147
|
1. For each comment thread above, open the link and read full context
|
|
107
|
-
2. Code comments: apply the fix
|
|
148
|
+
2. Code comments: apply the fix, commit
|
|
108
149
|
3. Questions / style: reply inline with a concise explanation
|
|
109
150
|
4. Use gh-pr-reply.sh --batch to post all replies in one shot
|
|
110
151
|
|
|
111
152
|
# Triggered when a PR has merge conflicts (mergeable_state=dirty).
|
|
112
|
-
# Placeholders: {repo}, {pr_number}, {pr_title}, {pr_url}, {head_branch},
|
|
153
|
+
# Placeholders: {repo}, {pr_number}, {pr_title}, {pr_url}, {head_branch},
|
|
154
|
+
# {base_branch}, {worktree_steps}
|
|
155
|
+
# {worktree_steps} is generated automatically from behavior.worktrees.mode.
|
|
113
156
|
on_merge_conflict:
|
|
114
157
|
instruction: |
|
|
115
158
|
PR #{pr_number} has merge conflicts with {base_branch}. Act immediately — no confirmation needed.
|
|
116
159
|
|
|
117
160
|
Use the Agent tool NOW to spawn a subagent with these instructions:
|
|
118
161
|
Resolve merge conflicts for PR #{pr_number} in {repo}:
|
|
119
|
-
|
|
120
|
-
2. cd /tmp/pr-{pr_number}-rebase && git fetch origin
|
|
121
|
-
3. git rebase origin/{base_branch} -- fix conflicts, then: git add -A && git rebase --continue
|
|
122
|
-
4. git push --force-with-lease origin {head_branch}
|
|
123
|
-
5. git worktree remove /tmp/pr-{pr_number}-rebase
|
|
162
|
+
{worktree_steps}
|
|
124
163
|
|
|
125
164
|
# Triggered when a PR is behind its base branch (mergeable_state=behind).
|
|
126
|
-
# Placeholders: {repo}, {pr_number}, {pr_title}, {pr_url}, {head_branch},
|
|
165
|
+
# Placeholders: {repo}, {pr_number}, {pr_title}, {pr_url}, {head_branch},
|
|
166
|
+
# {base_branch}, {worktree_steps}
|
|
167
|
+
# {worktree_steps} is generated automatically from behavior.worktrees.mode.
|
|
127
168
|
on_branch_behind:
|
|
128
169
|
instruction: |
|
|
129
170
|
PR #{pr_number} is behind {base_branch} (no conflicts). Act immediately — no confirmation needed.
|
|
130
171
|
|
|
131
172
|
Use the Agent tool NOW to spawn a subagent with these instructions:
|
|
132
173
|
Rebase PR #{pr_number} in {repo}:
|
|
133
|
-
|
|
134
|
-
2. cd /tmp/pr-{pr_number}-rebase && git fetch origin
|
|
135
|
-
3. git rebase origin/{base_branch}
|
|
136
|
-
4. git push --force-with-lease origin {head_branch}
|
|
137
|
-
5. git worktree remove /tmp/pr-{pr_number}-rebase
|
|
174
|
+
{worktree_steps}
|
|
138
175
|
|
|
139
176
|
# ── Code style guidelines ─────────────────────────────────────────────────────
|
|
140
177
|
# Free-text block prepended to every PR review notification.
|