@broject/bro 0.0.0 โ†’ 0.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Petr Plenkov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,208 @@
1
- # @broject/bro
1
+ # bro ๐Ÿค
2
2
 
3
- Placeholder for @broject/bro published by @nx-devkit/prepare-for-release.
3
+ > Your agent's sidekick. Skills are instructions โ€” **bro is the brain.**
4
+ >
5
+ > **Docs + landing:** https://theplenkov.github.io/bro/
6
+
7
+ Your AI agent can read a PR. Can it tell which merged PRs still have
8
+ unresolved review threads rotting in them? Can it say "bro, what's left?"
9
+
10
+ Now it can.
11
+
12
+ ```bash
13
+ npx @broject/bro debt prs # merged PRs nobody processed yet
14
+ npx @broject/bro debt collect # sweep them, label them debt:collected
15
+ npx @broject/bro debt status # the damage report
16
+ ```
17
+
18
+ ## What's the deal
19
+
20
+ Review bots dump comments on your PRs. You merge, the threads stay
21
+ unresolved, the findings evaporate. `bro` harvests them into a local
22
+ ledger (`.agents/review-debt/`) and slaps `debt:*` labels on the PRs it
23
+ already swept โ€” so nothing gets scanned twice and nothing hides.
24
+
25
+ ```text
26
+ PR merged โ†’ bro debt collect โ†’ findings land in .agents/review-debt/
27
+ โ†’ PR gets debt:collected (or debt:clean)
28
+ โ†’ you see exactly what's left: bro debt prs
29
+ ```
30
+
31
+ ## Install
32
+
33
+ ```bash
34
+ npx -y @broject/bro --help # zero install
35
+ npm i -g @broject/bro # or keep bro around: bro debt status
36
+ ```
37
+
38
+ Requires: `node >= 22`, `gh` authenticated, `bd`
39
+ ([beads](https://github.com/gastownhall/beads)) โ€” it's a default store, so
40
+ it's required unless you opt out. That's it. No tokens to babysit, no
41
+ config files to confess to. (Zero-beads fallback: `"stores": ["jsonl"]`
42
+ in `bro.config.json`.)
43
+
44
+ ## Install as an agent plugin
45
+
46
+ This repo is a plugin marketplace + registry โ€” one `bro` plugin packaged
47
+ per client:
48
+
49
+ | Client | Install |
50
+ | ------ | ------- |
51
+ | Devin | `devin plugins install ThePlenkov/bro` (or `ThePlenkov/bro#plugins/devin/bro`) |
52
+ | Claude Code | `/plugin marketplace add ThePlenkov/bro` โ†’ `/plugin install bro@bro` |
53
+ | Codex | `codex plugin marketplace add ThePlenkov/bro` โ†’ install `bro` |
54
+
55
+ Every adapter ships the same skills and lifecycle hooks (session
56
+ rehydration, review-gate stop, self-approve for `bro`/`bd`) wired through
57
+ `hooks/run.sh` โ€” local dist โ†’ `bro` on PATH โ†’ major-pinned `npx`, always
58
+ fail-open.
59
+
60
+ ## Commands
61
+
62
+ | Command | What bro does |
63
+ | ------- | ------------- |
64
+ | `bro debt collect` | Scans merged PRs missing a `debt:*` label, harvests unresolved threads, labels the PR `debt:collected` or `debt:clean` |
65
+ | `bro debt prs` | The queue โ€” merged PRs still unprocessed (`--all` for the full picture) |
66
+ | `bro debt status` | Ledger stats: open/done/wontfix, by area, by author, dupes |
67
+ | `bro debt list` | Raw rows, filterable |
68
+ | `bro debt mark <pr> <state>` | Manual override โ€” `skipped` is the human opt-out, bro respects it |
69
+ | `bro debt set <status> --thread-id ID` | Row status: `claimed` / `done --fix-pr N` / `wontfix` / `duplicate` โ€” feeds `sync` |
70
+ | `bro debt sync` | Projects the ledger into beads โ€” idempotent (`thread_id` โ†’ `external_ref`), so `bd ready -l debt` becomes the work queue. Needs `bd` installed; `.beads` auto-inits stealth when missing |
71
+ | `bro debt next [--claim] [--json]` | The top open finding โ€” priority-ranked, oldest first. The agent-fix primitive: claim it, fix it, `set done --fix-pr N` |
72
+ | `bro debt watch [--interval SEC]` | Collect on a timer (default 300s) โ€” post-merge bot comments get picked up by the stale-rescan without a manual run. All collect flags pass through |
73
+ | `bro act status [PR]` | **Exit gate as code** โ€” open threads, pending CI, SAST findings, mergeable. Non-zero while blocked. `--json` for machines |
74
+ | `bro act threads [PR]` | Unresolved review threads on the PR |
75
+ | `bro act resolve --thread ID [--comment T]` | Resolve (or `--unresolve`) โ€” replies first if a comment is given |
76
+ | `bro act reply --thread ID --comment T` | Reply without resolving; `--file TSV` for batch |
77
+ | `bro act wait [PR] [--merge]` | Poll the gate until it settles โ€” green, blockers, or timeout. `--merge` lands the PR on green โ€” the whole watcher loop in one command |
78
+ | `bro act merge [PR] [--squash\|--merge\|--rebase]` | Merge **only when the exit gate is green** โ€” refuses and names blockers when BLOCKED. Deletes the merged local branch too |
79
+ | `bro cleanup [--remote] [--dry-run]` | Delete local branches whose PR merged โ€” squash makes `git branch --merged` useless, so merged state comes from `gh pr list --state merged` |
80
+ | `bro drill down <title> [--under ID] [--ephemeral]` | Scoped descent โ€” a child frame under the current leaf, as a `drill`-labeled bead |
81
+ | `bro drill up --result T [--prevent T]โ€ฆ [--evidence R]โ€ฆ` | Ascend. `--result` is mandatory; each `--prevent` becomes a `discovered-from` task; evidence refs land in `bd provenance` (skipped for `--ephemeral` wisps) |
82
+ | `bro unwind โ€ฆ` | Alias for `drill up` |
83
+ | `bro drill current` / `tree` / `list` | Active leaf frame ยท all hierarchies ยท open frames |
84
+ | `bro drill distill <id>` | `bd mol distill` โ€” a good drill tree becomes a reusable proto |
85
+ | `bro wtf <complaint>` | Capture the user's frustration verbatim as a `wtf` bead โ€” timestamp + git snapshot included |
86
+ | `bro retrospect record <plan.toml>` | Validate a TOML retro plan and fan it out: `retro` bead + `prevention` beads per action, linked `discovered-from`, wtf answered |
87
+ | `bro retrospect status` | Exit gate โ€” non-zero while a `wtf` bead is unanswered. The agent can't self-declare "sorry, fixed" |
88
+ | `bro retrospect schema` / `list` | Print the commented TOML template ยท retros and open wtfs |
89
+ | `bro setup [--beads] [--skills]` | Wires bro into the current repo: checks `gh` auth + `bd`, writes `bro.config.json`, optionally `bd init --stealth` + installs the debt-pipeline formula and thin skill wrappers |
90
+ | `bro next [--list] [--json]` | **The autonomous loop's scheduler** โ€” claims the top ready bead (priority, then age) and prints the work order. Skips human gates, epics, and molecule steps. `bro next โ†’ implement โ†’ PR โ†’ merge โ†’ bd close โ†’ bro next` until `state: idle` โ€” no per-item "go?" prompts |
91
+ | `bro loop [--max N] [--dry-run]` | **The autonomous loop as a command** โ€” claim โ†’ worktree โ†’ spawn `loop.agent` โ†’ act gate โ†’ `bd close` โ†’ repeat. Review threads respawn the agent (โ‰ค `loop.fixRounds`); failures land as bead notes, never silent |
92
+
93
+ ## The pipeline (beads)
94
+
95
+ `bro setup --beads` drops `debt-pipeline.formula.toml` into `.beads/formulas/`:
96
+
97
+ ```bash
98
+ bd mol pour debt-pipeline
99
+ # collect โ†’ HUMAN GATE (triage) โ†’ fix โ†’ PR gate โ†’ sync
100
+ ```
101
+
102
+ Every step is a `bro` command; the human gate is the point. bro collects
103
+ and carries โ€” the verdict is yours.
104
+
105
+ ## Config (optional)
106
+
107
+ `bro.config.json` in the repo root โ€” written per-clone by `bro setup` and
108
+ gitignored on purpose (store choices are machine-local), so fresh checkouts
109
+ run on defaults until they set up. Everything's optional:
110
+
111
+ ```json
112
+ {
113
+ "stores": ["jsonl", "beads"],
114
+ "personality": "terse",
115
+ "debt": {
116
+ "dir": ".agents/review-debt",
117
+ "sources": ["review-threads", "dependabot", "secret-scanning"],
118
+ "stale_days": 14
119
+ },
120
+ "connectors": { "reviews": "github", "tasks": "beads" },
121
+ "sdd": { "mode": "remind", "dir": "specs" }
122
+ }
123
+ ```
124
+
125
+ `connectors` pins which registered connector serves a facade when several
126
+ could โ€” e.g. a self-hosted GitHub Enterprise or a future GitLab/Jira
127
+ connector. With one provider per facade it can be omitted; remote-URL
128
+ matching auto-detects github.com anyway.
129
+
130
+ `sdd` opts the repo into spec-driven development: `remind` nudges via
131
+ session/prompt hook context when a claimed bead lacks `specs/<id>.md`
132
+ (or a `spec:` link), `gate` also lets the stop gate block once. Commit
133
+ the section โ€” it then applies to every agent in the repo.
134
+
135
+ `stores` lists the backends debt writes to. `jsonl` is the evidence ledger
136
+ (always written โ€” drop it and bro adds it back). `beads` is on **by
137
+ default**: a normal collect auto-runs `bd init --stealth --skip-agents
138
+ --skip-hooks` when a repo is missing `.beads` (skipped by `--dry-run`,
139
+ `--list-only`, and an empty target list), and
140
+ projects every record into `bd` โ€” JSONL keeps the receipts, beads runs the
141
+ queue. Opt out with an explicit `"stores": ["jsonl"]`. Requires `bd`
142
+ installed; a missing bd fails the run after evidence is written.
143
+
144
+ The ledger dir is machine-local state too โ€” bro adds it to
145
+ `.git/info/exclude` on first write so harvest evidence can't be committed
146
+ by accident.
147
+
148
+ `debt.sources` picks which collectors `bro debt collect` runs. The
149
+ default is `["review-threads"]` โ€” the original merged-PR sweep. Opt-in
150
+ sources feed the same ledger and beads projection (`debt:<source>`
151
+ labels, `thread_id` is the source's stable key):
152
+
153
+ | Source | Feeds on |
154
+ | ------ | -------- |
155
+ | `review-threads` | Unresolved review threads on merged PRs (default) |
156
+ | `dependabot` | Open Dependabot alerts โ€” skipped when an open `dependabot/*` PR already covers the dependency |
157
+ | `code-scanning` | Open code-scanning alerts (rule + file ref) |
158
+ | `secret-scanning` | Open secret-scanning alerts โ€” always blocking priority |
159
+ | `stale-prs` | Open PRs idle > `debt.stale_days` days or failing checks (WIP drafts don't count) |
160
+ | `failed-ci` | Latest default-branch workflow run, if it failed |
161
+
162
+ Alert sources reconcile both ways: a finding that disappears upstream is
163
+ marked `done` in the ledger on the next collect.
164
+
165
+ ## Labels bro manages
166
+
167
+ | Label | Meaning |
168
+ | ----- | ------- |
169
+ | `debt:collected` | Swept, findings in the ledger |
170
+ | `debt:clean` | Swept, nothing found โ€” bro won't look twice |
171
+ | `debt:skipped` | You told bro to chill. bro chills. |
172
+
173
+ ## Philosophy
174
+
175
+ bro doesn't fix your code. bro doesn't write essays in your PRs. bro
176
+ collects what's owed, keeps the books clean, and waits. bro got you.
177
+
178
+ ## Dev
179
+
180
+ ```bash
181
+ git clone https://github.com/theplenkov/bro
182
+ cd bro && npm install
183
+ npm run build && npm test
184
+ ```
185
+
186
+ Workspace packages live in `packages/*` (`@broject/core`, `@broject/debt`, `@broject/act`,
187
+ the CLI itself). Skills in `skills/` are thin wrappers โ€” all mechanics are in
188
+ the CLI. Nx inference comes from the published `@nx-devkit/*` plugins.
189
+
190
+ ## Releasing
191
+
192
+ CI-driven, human-gated. `Actions โ†’ Release โ†’ Run workflow`:
193
+
194
+ - `specifier` โ€” `auto` derives the bump from conventional commits since
195
+ the last `v*` tag (`feat:` โ†’ minor, fixes โ†’ patch, `BREAKING` โ†’ major,
196
+ 0.x shifted), or pick `patch` / `minor` / `major` / `prerelease`.
197
+ - `preid` โ€” set (e.g. `beta`) to cut `vX.Y.Z-beta.N` instead.
198
+ - `dryRun` โ€” prints the nx release plan, changes nothing.
199
+
200
+ The workflow runs `nx release version` on the `main` checkout, commits
201
+ the bump to a `release/vX.Y.Z` branch, and opens a PR. Merge it โ†’
202
+ `release-tag.yml` cuts the `v*` tag + GitHub
203
+ release on `main` and dispatches `publish.yml`, which ships to npm via
204
+ OIDC trusted publishing. No tokens, no manual tags. `release-tag.yml`
205
+ can also be run manually (`Actions โ†’ Tag Release`) to catch up a version
206
+ that predates the pipeline.
207
+
208
+ MIT. PRs welcome โ€” bro reviews them anyway.