{"_id":"@brokkai/feature-bot","_rev":"5-c66763482279fd5be983fc27ddfd713b","name":"@brokkai/feature-bot","dist-tags":{"next":"0.1.0-rc.1","latest":"0.1.2"},"versions":{"0.1.0-rc.1":{"name":"@brokkai/feature-bot","version":"0.1.0-rc.1","license":"Apache-2.0","_id":"@brokkai/feature-bot@0.1.0-rc.1","maintainers":[{"name":"bigslopdave","email":"david@brokk.ai"},{"name":"foundev","email":"tech@foundev.pro"}],"homepage":"https://github.com/BrokkAi/feature-bot#readme","bugs":{"url":"https://github.com/BrokkAi/feature-bot/issues"},"os":["linux","darwin"],"bin":{"bfb":"bin/bfb.cjs"},"cpu":["x64","arm64"],"dist":{"shasum":"288579465f3cf283bd0fd49cb4c83d9cf0bedf96","tarball":"https://registry.npmjs.org/@brokkai/feature-bot/-/feature-bot-0.1.0-rc.1.tgz","fileCount":6,"integrity":"sha512-fFwrw9e4VsfAfdE3/nlvSvfOZ+WIc+zaKC3xJXlyFzxrHtKwSlmOQCp3+Zl/PhEek/obFDJdXADPHlKI3JnjVw==","signatures":[{"sig":"MEQCIE4Qjsq5QmCKDyPopI2/bPkAUS5I2xOr+Y7+PAvpJVrzAiBGagqbyi/PJhhwMSg6o8g3dqddhPmbaEykt5XSK8QHGg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":53789},"_from":"file:/private/tmp/feature-bot-release-0.1.0-rc.1/packages/npm/brokkai-feature-bot-0.1.0-rc.1.tgz","engines":{"node":">=18"},"_npmUser":{"name":"foundev","email":"tech@foundev.pro"},"_resolved":"/private/tmp/feature-bot-release-0.1.0-rc.1/packages/npm/brokkai-feature-bot-0.1.0-rc.1.tgz","_integrity":"sha512-fFwrw9e4VsfAfdE3/nlvSvfOZ+WIc+zaKC3xJXlyFzxrHtKwSlmOQCp3+Zl/PhEek/obFDJdXADPHlKI3JnjVw==","repository":{"url":"git+https://github.com/BrokkAi/feature-bot.git","type":"git"},"_npmVersion":"12.0.2","description":"Brokk Feature Bot: autonomous feature discovery and duplicate-aware GitHub issue proposals","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"optionalDependencies":{"@brokkai/feature-bot-linux-x64":"0.1.0-rc.1","@brokkai/feature-bot-darwin-x64":"0.1.0-rc.1","@brokkai/feature-bot-linux-arm64":"0.1.0-rc.1","@brokkai/feature-bot-darwin-arm64":"0.1.0-rc.1"},"_npmOperationalInternal":{"tmp":"tmp/feature-bot_0.1.0-rc.1_1789055287806_0.8943025630204711","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@brokkai/feature-bot","version":"0.1.0","license":"Apache-2.0","_id":"@brokkai/feature-bot@0.1.0","maintainers":[{"name":"jbellis","email":"jbellis@gmail.com"},{"name":"bigslopdave","email":"david@brokk.ai"},{"name":"foundev","email":"tech@foundev.pro"}],"homepage":"https://github.com/BrokkAi/feature-bot#readme","bugs":{"url":"https://github.com/BrokkAi/feature-bot/issues"},"os":["linux","darwin"],"bin":{"bfb":"bin/bfb.cjs"},"cpu":["x64","arm64"],"dist":{"shasum":"349b7f8e485ec2d3da69303ebcaa1395a5246291","tarball":"https://registry.npmjs.org/@brokkai/feature-bot/-/feature-bot-0.1.0.tgz","fileCount":6,"integrity":"sha512-hCuRKuOn4j8o0qUa8Si6zn+itHfKe7RFPvOYivMUZELt2mo/oVN1VcV9IHW3cUkoz5vOlcfo4IsSolCQJ25EyA==","signatures":[{"sig":"MEUCIQCdL9YsdbrulvIHK46YNDxEw4EANA4d+b8yve0U4wEYbAIgRDGR8XqGyQ3j4LNazt6wFnxDJ8iesC3NnGoPykZvuoE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@brokkai%2ffeature-bot@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":54949},"_from":"file:/home/runner/work/feature-bot/feature-bot/dist/packages/npm/brokkai-feature-bot-0.1.0.tgz","engines":{"node":">=18"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c00fee80-eb6c-42f1-9c66-d7b81d683b43"}},"_resolved":"/home/runner/work/feature-bot/feature-bot/dist/packages/npm/brokkai-feature-bot-0.1.0.tgz","_integrity":"sha512-hCuRKuOn4j8o0qUa8Si6zn+itHfKe7RFPvOYivMUZELt2mo/oVN1VcV9IHW3cUkoz5vOlcfo4IsSolCQJ25EyA==","repository":{"url":"git+https://github.com/BrokkAi/feature-bot.git","type":"git"},"_npmVersion":"11.19.0","description":"Brokk Feature Bot: autonomous feature discovery and duplicate-aware GitHub issue proposals","directories":{},"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"optionalDependencies":{"@brokkai/feature-bot-linux-x64":"0.1.0","@brokkai/feature-bot-darwin-x64":"0.1.0","@brokkai/feature-bot-linux-arm64":"0.1.0","@brokkai/feature-bot-darwin-arm64":"0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/feature-bot_0.1.0_1789374575223_0.3652323249535494","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@brokkai/feature-bot","version":"0.1.1","license":"Apache-2.0","_id":"@brokkai/feature-bot@0.1.1","maintainers":[{"name":"jbellis","email":"jbellis@gmail.com"},{"name":"bigslopdave","email":"david@brokk.ai"},{"name":"foundev","email":"tech@foundev.pro"}],"homepage":"https://github.com/BrokkAi/feature-bot#readme","bugs":{"url":"https://github.com/BrokkAi/feature-bot/issues"},"os":["linux","darwin"],"bin":{"bfb":"bin/bfb.cjs"},"cpu":["x64","arm64"],"dist":{"shasum":"a1f1d02780bbf2c9e97db658b7b431e73b7bded8","tarball":"https://registry.npmjs.org/@brokkai/feature-bot/-/feature-bot-0.1.1.tgz","fileCount":6,"integrity":"sha512-EDKBNpCpxbv9kmr3PSb6cvJHAJhCb2GgPulo68rjVcbPY3Xqb2hOfy5DdppmBKpQ7xyTlWj/xZpriqsP3jfhlA==","signatures":[{"sig":"MEYCIQCHt9RJ42d63taM3zSZiE8IErM3Ws/SnSVE+wx7IEdd4wIhAOpuVMyERI6qqbzniIDiaNjSnqtOIFjmhoGxCOCyMJo2","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@brokkai%2ffeature-bot@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":54949},"_from":"file:/home/runner/work/feature-bot/feature-bot/dist/packages/npm/brokkai-feature-bot-0.1.1.tgz","engines":{"node":">=18"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c00fee80-eb6c-42f1-9c66-d7b81d683b43"}},"_resolved":"/home/runner/work/feature-bot/feature-bot/dist/packages/npm/brokkai-feature-bot-0.1.1.tgz","_integrity":"sha512-EDKBNpCpxbv9kmr3PSb6cvJHAJhCb2GgPulo68rjVcbPY3Xqb2hOfy5DdppmBKpQ7xyTlWj/xZpriqsP3jfhlA==","repository":{"url":"git+https://github.com/BrokkAi/feature-bot.git","type":"git"},"_npmVersion":"11.19.0","description":"Brokk Feature Bot: autonomous feature discovery and duplicate-aware GitHub issue proposals","directories":{},"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"optionalDependencies":{"@brokkai/feature-bot-linux-x64":"0.1.1","@brokkai/feature-bot-darwin-x64":"0.1.1","@brokkai/feature-bot-linux-arm64":"0.1.1","@brokkai/feature-bot-darwin-arm64":"0.1.1"},"_npmOperationalInternal":{"tmp":"tmp/feature-bot_0.1.1_1789376707517_0.4532374157395824","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"os":["linux","darwin"],"_id":"@brokkai/feature-bot@0.1.2","bin":{"bfb":"bin/bfb.cjs"},"cpu":["x64","arm64"],"bugs":{"url":"https://github.com/BrokkAi/feature-bot/issues"},"dist":{"shasum":"b2865b835c802b7e48d9e8648e900689e419d07d","tarball":"https://registry.npmjs.org/@brokkai/feature-bot/-/feature-bot-0.1.2.tgz","fileCount":6,"integrity":"sha512-nxanRSmVyQu3IhhIuLrLD7ewGri88fGI41FDfPyL8sD15jsmLDp3CfckurDEZAGYvdIAFQPc+aAPvr4AURIXZA==","signatures":[{"sig":"MEUCIAd+eyul+t1sLxdFjMTetvQlg08hxvHZtKgfJsVFBXyVAiEAz8kzHwxacAtSMEpuWy6OTAAiRcPZYvZxP54Qmlcu5GI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGayLjBoY5kdnWrt2v1EuGmKgnpXscdPzvSlk/mWdwe0AiEAxzDPBgemkpQxGEGsBnD/JiNiswRhV58N1/vPS9Aj0fc="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@brokkai%2ffeature-bot@0.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":58536},"name":"@brokkai/feature-bot","_from":"file:/home/runner/work/feature-bot/feature-bot/dist/preflight/de2db2e07ef6c15c2a05c5db623b7fe22ef40c1a/v0.1.2/packages/npm/brokkai-feature-bot-0.1.2.tgz","engines":{"node":">=18"},"license":"Apache-2.0","version":"0.1.2","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c00fee80-eb6c-42f1-9c66-d7b81d683b43"}},"homepage":"https://github.com/BrokkAi/feature-bot#readme","_resolved":"/home/runner/work/feature-bot/feature-bot/dist/preflight/de2db2e07ef6c15c2a05c5db623b7fe22ef40c1a/v0.1.2/packages/npm/brokkai-feature-bot-0.1.2.tgz","_integrity":"sha512-nxanRSmVyQu3IhhIuLrLD7ewGri88fGI41FDfPyL8sD15jsmLDp3CfckurDEZAGYvdIAFQPc+aAPvr4AURIXZA==","repository":{"url":"git+https://github.com/BrokkAi/feature-bot.git","type":"git"},"_npmVersion":"11.19.0","description":"Brokk Feature Bot: autonomous feature discovery and duplicate-aware GitHub issue proposals","directories":{},"maintainers":[{"name":"jbellis","email":"jbellis@gmail.com"},{"name":"bigslopdave","email":"david@brokk.ai"},{"name":"foundev","email":"tech@foundev.pro"}],"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"optionalDependencies":{"@brokkai/feature-bot-linux-x64":"0.1.2","@brokkai/feature-bot-darwin-x64":"0.1.2","@brokkai/feature-bot-linux-arm64":"0.1.2","@brokkai/feature-bot-darwin-arm64":"0.1.2"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/feature-bot_0.1.2_1789475733576_0.2873408346751605"}}},"time":{"created":"2026-09-10T15:48:07.636Z","modified":"2026-09-15T12:35:34.070Z","0.1.0-rc.1":"2026-09-10T15:48:07.961Z","0.1.0":"2026-09-14T08:29:35.351Z","0.1.1":"2026-09-14T09:05:07.666Z","0.1.2":"2026-09-15T12:35:33.683Z"},"bugs":{"url":"https://github.com/BrokkAi/feature-bot/issues"},"license":"Apache-2.0","homepage":"https://github.com/BrokkAi/feature-bot#readme","repository":{"url":"git+https://github.com/BrokkAi/feature-bot.git","type":"git"},"description":"Brokk Feature Bot: autonomous feature discovery and duplicate-aware GitHub issue proposals","maintainers":[{"name":"jbellis","email":"jbellis@gmail.com"},{"name":"bigslopdave","email":"david@brokk.ai"},{"name":"foundev","email":"tech@foundev.pro"}],"readme":"# Brokk Feature Bot\n\n<img src=\"https://raw.githubusercontent.com/BrokkAi/feature-bot/master/docs/feature-reader.png\" alt=\"Studious feature bot with glasses and an open book\" width=\"200\">\n\nResearch valuable new features in a repository and file concrete GitHub proposals.\n`bfb` is modeled on [bug-bot](https://github.com/BrokkAi/bug-bot) (`bbb`), with a\nfeature-specific research prompt, proposal schema, and independent state. It follows\nthe same Go CLI, no-config discovery, managed workspace, and shared\n[ACP runner](https://github.com/BrokkAi/acp-go) pattern as\n[issue-bot](https://github.com/BrokkAi/issue-bot) (`bib`) and\n[release-bot](https://github.com/BrokkAi/release-bot) (`brb`).\n\n**The LLM decides whether a finding duplicates an existing issue.** It compares\nuser goals, capabilities, scope, and discussion across open and closed issues.\nThere are no title similarity thresholds or feature fingerprint rules. Proposals\nmust fit the repository's purpose, demonstrate a capability gap, explain user\nvalue, and include bounded scope and testable acceptance criteria. Bug fixes,\nrefactors-only, speculative wishlists, and previously rejected features are excluded.\n\n## Install and run\n\nThe initial prerelease is `v0.1.0-rc.1`, available under npm's `next` channel\nonce its publication completes. Use `npm install -g @brokkai/feature-bot@next`\nfor prereleases. The stable installation commands below become available when a\nstable release is published. To build a source checkout, run `make build`.\n\nInstall with npm (Node.js 18+; no Go toolchain required):\n\n```sh\nnpm install -g @brokkai/feature-bot\nbfb /path/to/your-repo\n```\n\nFor a single invocation, use `npx --yes @brokkai/feature-bot`. Keep npm optional\ndependencies enabled: they supply the native Linux/macOS x64 or arm64 binary.\n\nOr install a native binary with its SHA-256 checksum verified:\n\n```sh\ncurl -fsSL https://raw.githubusercontent.com/BrokkAi/feature-bot/master/install.sh | sh\n```\n\nThe installer puts `bfb` in `~/.local/bin`; add that directory to `PATH`.\nSet `INSTALL_DIR` to change the destination. To pin a version, download the\nscript and run `sh install.sh v0.1.0`.\n\nWith Go 1.27.1 or newer:\n\n```sh\ngo install github.com/BrokkAi/feature-bot/cmd/bfb@latest\n```\n\nGo installs `bfb` in `GOBIN`, or `$(go env GOPATH)/bin` by default.\nFrom a source checkout:\n\n```sh\nmake build\n./bin/bfb /path/to/your-repo\n./bin/bfb /path/to/your-repo --plain\n./bin/bfb once /path/to/your-repo --dry-run\n./bin/bfb once /path/to/your-repo --focus \"onboarding and reporting workflows\"\n./bin/bfb /path/to/your-repo --max-issues 2 --label enhancement\n./bin/bfb /path/to/your-repo --model YOUR_MODEL_ID --effort low\n./bin/bfb status /path/to/your-repo\n./bin/bfb report /path/to/your-repo --branch master --status dry_run > proposals.md\n./bin/bfb version\n./bin/bfb retry /path/to/your-repo --once\n```\n\nSource builds require Go 1.27.1. To install the local source as `bfb`, run\n`go install ./cmd/bfb` and put your Go bin directory on `PATH`.\nRunning `bfb` from inside any target repository discovers its remote and default\nbranch. A Git URL also works. Flags can precede or follow the repository argument.\n\n`bfb version` prints the embedded release tag. Local builds report `dev`; binaries installed with `go install ...@version` report the module version.\n\nRuntime requirements: Git, authenticated `gh` with repository/issue read and\nissue creation access, and an authenticated ACP agent. By default it uses an\ninstalled `codex-acp`, falling back to `npx --yes @agentclientprotocol/codex-acp`.\nExplicit `--agent` commands are used as supplied; repeat `--agent-arg` for arguments.\n\nStarting `bfb` authorizes unattended local investigation, test execution, and\ncreation of issues for the selected repository. `--dry-run` performs discovery\nand review, prints the proposed issue bodies, and saves them without filing.\n\n## Terminal dashboard\n\nInteractive runs show a live dashboard with a studious spectacles-and-book motif.\nIt fits the current terminal\nor tmux pane, adjusts when the pane is resized, and keeps the repository and\ncurrent task visible. Each pane still runs one repository.\n\n```sh\nbfb /path/to/repo           # live dashboard in an interactive terminal\nbfb /path/to/repo --plain   # scrolling console output and agent transcript\nbfb /path/to/repo --json    # structured logs for tools and log collectors\n```\n\nThe overview shows the repository, branch and commit, scan stage, active tool,\nuptime, attempt budget, and next check or retry countdown. Larger panes also\nshow the selected model, reasoning effort, and investigation focus.\n\n**Saved** counts cover findings in the configured repository/branch state,\nincluding the current scan: found, filed, duplicate, pending, dry run, and skipped\n(invalid, uncertain, or stale). **Run** counters start at zero each time the\nprocess starts: completed scans, attempts, agent starts, tools, and error log\nevents. A discovered finding is counted as filed only after publication is\nconfirmed. Findings restored after restarting are included in saved totals.\n\n- `1`, `2`, `3` or `Tab`: switch between overview, proposals, and activity.\n- `↑` / `↓` or `k` / `j`: browse findings or scroll activity.\n- `Enter`: inspect the selected proposal, issue URL, scope, acceptance criteria, and review.\n- `Esc`: return from finding details. `Page Up` / `Page Down` scroll details.\n- `g` / `G`: jump to the start/end; `G` resumes following live activity.\n- `q` or `Ctrl+C`: stop the bot and its active agent, then restore the terminal.\n\nThe finding browser shows the latest 200 findings, while totals include all saved\nfindings. The activity view keeps recent output; full agent transcripts remain\nunder the state directory. On exit, a short summary and new finding URLs stay in\nthe terminal. `once` exits after its scan, and dry runs also print proposed finding\ndetails on exit.\n\nPiped input, redirected stderr, and `TERM=dumb` use scrolling output automatically.\n`--plain` and `--json` disable the dashboard and are mutually exclusive.\n`NO_COLOR` disables dashboard colors. `status`, `report`, `version`, and help keep their\nexisting output and never open the dashboard.\n\n## How it works\n\n1. Fetch the target branch into a managed clone and make an isolated detached\n   worktree for the scan. The original checkout and uncommitted work are preserved.\n2. Download all open and closed issues and their comments with pagination. Give\n   the investigator the complete snapshot and recent scan summaries so it can\n   avoid known proposals and explore new areas on subsequent scans.\n3. Have the agent study project purpose, current workflows, source, docs, and tests.\n   Each candidate must include a specific user problem, current workflow or workaround,\n   proposed behavior, user value, scope and non-goals, testable acceptance criteria,\n   existing source paths, and evidence of both a gap and implementation feasibility.\n   The researcher must distinguish observations from assumptions and may return zero findings.\n4. Start separate LLM review sessions to verify the evidence and compare each\n   candidate against the issue history. Large histories are supplied in batches;\n   every issue and comment is included, and each response must identify all issue\n   numbers it reviewed. Coverage errors report the expected count and missing,\n   repeated, and unexpected numbers (up to 20 per category). A rejected coverage\n   receipt gets one corrective attempt with the required number set and validation\n   error. Successful batches are saved and reused after restart when their content,\n   candidate, and source revision still match; changed batches are reviewed again.\n   Exhausted corrections leave the candidate pending and block publication.\n   A duplicate verdict links the existing report in local\n   state. Uncertain and invalid findings are saved without filing.\n5. Refresh issues before publication. New or edited reports go back to the LLM\n   for comparison. Recheck the source commit and tracked files. An optional\n   operator verifier can provide an additional gate.\n6. Create issues sequentially, including scope, acceptance criteria, evidence, and the review\n   explanation. Each newly created issue is available to the next candidate's\n   LLM review, including candidates from the same scan.\n\nClosed issues count as known proposals, including implemented, duplicate, rejected,\nor wontfix features. A reconsideration belongs to that existing issue. The bot does\nnot reopen or comment on it. The reviewer independently checks that a feature is\nnot already supported and rejects bug fixes or refactors without a new capability.\n\nThe default is at most **three issues per scan**, a **two-hour attempt budget**,\nand another scan **30 minutes after completion**, even if the commit is unchanged.\nRecent summaries guide exploration; this is not a claim of exhaustive coverage.\n`once` runs or resumes one scan and exits. When an agent completes its research\nbut the final `FEATURE_RESULT` or `FEATURE_REVIEW` line is truncated, fenced, or\nfollowed by prose, the daemon asks the agent once to restate that receipt from\nits own answer before treating the attempt as failed; the restated receipt is\nvalidated exactly like a first-pass one. Failed scans retain their candidates,\nworkspace, and diagnostics; retries wait at least 15 minutes and run on the next\npoll, with three attempts before requiring `retry`. Agent setup errors stop the\ndaemon without consuming an attempt. An advanced branch invalidates pending\nfindings so the next eligible attempt scans the new commit.\n\n## Duplicate handling and interrupted requests\n\nSemantic duplicate detection is an LLM judgment, so it is not a guarantee.\nIncomplete history, malformed review responses, and uncertain comparisons stop\npublication. Same-title reports still reach the LLM: identical wording can hide\ndifferent capabilities, and different wording can describe the same feature.\n\nEvery planned issue gets a random request ID, saved **before** sending its create\nrequest and embedded as a hidden comment in the issue body. This ID identifies\none publication attempt; it is not derived from feature content or used to classify\nduplicates. After a crash or lost response, `bfb` looks for that ID and records\nthe existing issue. If its outcome is unknown and the ID is not visible, it\nrefuses to send another create request. Run `once` to try reconciliation again.\nIf it never appears, inspect GitHub and the saved state before repairing the\npending entry; `retry` intentionally cannot blindly resend an ambiguous request.\n\nConfirmed HTTP rejections, such as validation or permission failures, keep the\ncandidate pending. Correct the request or access problem, then run `once` to\nresume, or `retry --once` if the attempt budget is exhausted. Timeouts, server\nerrors, and incomplete responses still require marker reconciliation. Older\nversions saved every create error as ambiguous; those existing `posting` entries\nstill require inspection when no marker appears.\n\nA per-repository local lock coordinates instances across branches and config\npaths using the same state home. Different machines/accounts and simultaneous\nhuman reports cannot be locked atomically with GitHub issue creation. Run one\nactive `bfb` per repository to avoid that race.\n\n## Brokk Town worker service\n\n`bfb worker --socket PATH` serves one-shot feature research operations to Brokk\nTown over a private Unix-domain socket. The socket is mode `0600`; the endpoint is\nprivate to the local service, and the process exits after Town requests shutdown.\n\nWorker protocol v1 uses standard-library HTTP with JSON messages:\n\n- `GET /v1/initialize` returns the protocol range, bot identity, release version,\n  and capabilities. Town requires `feature-research` as well as common `run` and\n  `progress` capabilities. Workers supporting optional discovery controls also\n  advertise `feature-research-controls`.\n- `POST /v1/runs` accepts one strict JSON task and responds with contiguous\n  newline-delimited JSON events: `progress`, optional typed `result`,\n  and `error`, `canceled`, or `complete`.\n- `POST /v1/shutdown` asks the service to stop after the current stream.\n\nA run request may include the optional `feature_research` object alongside its\nrepository and agent settings, for example:\n\n```json\n{\n  \"protocol\": 1,\n  \"remote\": \"https://github.com/OWNER/REPO.git\",\n  \"branch\": \"main\",\n  \"directory\": \"/srv/bfb/checkout\",\n  \"state_directory\": \"/srv/bfb/state\",\n  \"repo\": \"OWNER/REPO\",\n  \"host\": \"github.com\",\n  \"agent\": {\"command\": [\"codex-acp\"]},\n  \"feature_research\": {\"focus\": \"onboarding\", \"max_issues\": 1}\n}\n```\n\n`focus` is a string and defaults to empty (unrestricted research). `max_issues`\nis an integer from 1 through 20 and defaults to 3 when omitted; explicit zero\nis invalid. Either field may be omitted, and each request starts with fresh\ndefaults. Unknown fields and incorrect types are rejected. A fresh discovery\nprompt receives these settings and its receipt may contain zero findings, but\ncannot exceed the maximum.\n\nThese options follow CLI `--focus` and `--max-issues` semantics: they control\ndiscovery. Resuming an already-discovered scan preserves its saved candidates;\nnew options do not redirect research, regenerate or truncate that saved work.\nReconciliation, independent review and publication gates continue to apply.\nClients must detect the capability and include the optional fields to use them.\n\nVersion and capability negotiation happen before work starts. Town does not read\nthis bot's private state files; issue and review outcomes are explicit protocol\nresults when applicable, while GitHub remains the durable source for receipts.\nThe schemas are independent of the Unix HTTP transport, allowing an authenticated\nTLS transport to be added later without changing worker semantics.\n\n## Optional configuration\n\n`bfb --config feature-bot.json` loads a strict JSON object. No file is loaded or\ngenerated implicitly. Paths are resolved relative to the configuration file.\nSee [feature-bot.example.json](feature-bot.example.json).\n\n```json\n{\n  \"remote\": \"https://github.com/OWNER/REPO.git\",\n  \"branch\": \"main\",\n  \"directory\": \"var/checkout\",\n  \"state_directory\": \"var/state\",\n  \"poll\": \"30m\",\n  \"timeout\": \"2h\",\n  \"retry_delay\": \"15m\",\n  \"attempts\": 3,\n  \"max_issues\": 3,\n  \"focus\": \"\",\n  \"labels\": [],\n  \"dry_run\": false,\n  \"agent\": {\"command\": [\"codex-acp\"]}\n}\n```\n\nLabels are optional and added only to new issues; they never filter the history.\nUse labels that already exist in the target repository. `github.host` supports\nEnterprise, and `github.repo` (`OWNER/REPO`) identifies a local mirror's GitHub\nrepository. `agent` also supports `environment`, `auth_method`, `mode`, `model`,\nand `effort`, with selection handled by the shared ACP runner.\n\n`verify` accepts an argument array, such as `[\"/opt/checks/verify-feature\"]`, executed\nin the scan worktree with `FEATURE_COMMIT` and JSON `FEATURE_FINDING` in its environment.\nKeep operator verifiers outside the writable worktree. A nonzero exit blocks filing.\n\n## State and execution\n\nState defaults to `$XDG_STATE_HOME/feature-bot` or `~/.local/state/feature-bot`, keyed by\nremote and branch. JSON state is replaced atomically with fsync; private session\ntranscripts live under the state directory. `status` prints saved JSON without\nstarting an agent. `--json` selects structured progress logs.\n\n### Saved proposal reports\n\n`report` writes Markdown to stdout for every saved completed and active candidate,\nincluding findings beyond the dashboard's 200-entry limit. It includes repository,\nbranch, saved status, available issue or duplicate URL, proposal fields, and\nindependent review. Redirect stdout to save or share it:\n\n```sh\nbfb report --config feature-bot.json > proposals.md\nbfb report --config feature-bot.json --status dry_run > dry-run-proposals.md\nbfb report /path/to/repo --branch master > proposals.md\n```\n\nOmit `--status` to include all candidates. Supported filters are `pending`,\n`posting`, `submitted`, `duplicate`, `uncertain`, `invalid`, `dry_run`, and `stale`.\nMissing state or a filter with no matches produces an explicit no-findings report.\n\nReporting only reads saved state: it starts no scan or agent and does not require\n`gh` or an ACP executable. Explicit configuration permits fully local reading;\nwith repository discovery, pass `--branch` to avoid a default-branch network\nlookup. Use the same configuration and branch as the original run.\nReports omit commit attribution because completed candidates do not retain their\noriginal commit. Internal workspace paths, transcripts, and publication markers\nare not included as metadata. Proposal and review prose is preserved as Markdown;\nreview that content before sharing it.\n\nScan worktrees and research files are retained for inspection. Manage their\nretention along with transcripts externally. Agent instructions prohibit feature implementation, fixes,\ncommits, pushes, and direct GitHub writes; tracked source changes or a changed\nHEAD invalidate the scan. Evidence is independently reviewed by the LLM, not\nproof that tests are correct. As in the sibling bots, ACP permission requests\nare automatically approved and agent commands run with the account's OS rights.\nThis is not a sandbox; use an appropriate account/container for the repository.\n\n## Development and packaging\n\n```sh\nmake check build\n./bin/bfb --help\npython3 -m unittest discover -s scripts -p '*_test.py'\nnode --test --test-isolation=none npm/bfb.test.cjs\n```\n\nTests use local Git fixtures and simulated ACP/GitHub outcomes; they do not run\na paid model or create real issues. They cover semantic closed duplicates,\nsame-title distinct features, rejected proposals, uncertain value or feasibility,\nfeature receipt completeness, concurrent reports, partial histories, source changes,\ndry runs, retries, ambiguous POSTs, receipt coverage, configuration, locks, progress snapshots, dashboard resizing, and terminal cleanup.\n\nThe inherited release workflow packages Linux/macOS amd64/arm64 archives with\nchecksums. The npm launcher and packaging workflow target `@brokkai/feature-bot`\nand install `bfb`. See [RELEASING.md](RELEASING.md) for publication and verification.\n\nAPI references: [GitHub issues](https://docs.github.com/en/rest/issues/issues),\n[issue comments](https://docs.github.com/en/rest/issues/comments).\n## Automatic releases\n\nPush a new `v*` version tag to run the complete **Publish packages** pipeline:\nLinux/macOS checks, native GitHub assets, then all five npm packages from the\nsame tag and commit. No manual package dispatch is needed. The package job runs\nonly after native publication succeeds and validates package contents and local\ninstalls before uploading. It does not wait for npm's public index to update.\n\nFor recovery, rerun failed jobs or manually dispatch `publish-packages.yml` from\nthe exact existing tag with `publish=true`. The default manual `publish=false`\nvalidates without uploading. Existing published bytes must match on retry.\nSee [RELEASING.md](RELEASING.md) for details.\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) and our\n[Code of Conduct](CODE_OF_CONDUCT.md). Report vulnerabilities privately using\n[SECURITY.md](SECURITY.md).\n\n## License\n\nLicensed under [Apache-2.0](LICENSE). See [NOTICE](NOTICE) for project\nattribution and [licenses/README.md](licenses/README.md) for dependency terms,\nthird-party notices, and the license review process.\n","readmeFilename":"README.md"}