@backburner/cli 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 (202) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +329 -0
  3. package/dist/src/agents/antigravity-launch.js +162 -0
  4. package/dist/src/agents/antigravity.js +251 -0
  5. package/dist/src/agents/claude-launch.js +117 -0
  6. package/dist/src/agents/claude.js +271 -0
  7. package/dist/src/agents/codex-launch.js +82 -0
  8. package/dist/src/agents/codex.js +261 -0
  9. package/dist/src/agents/composite-runner.js +13 -0
  10. package/dist/src/agents/extraction.js +442 -0
  11. package/dist/src/agents/failure-feedback.js +132 -0
  12. package/dist/src/agents/gemini-launch.js +96 -0
  13. package/dist/src/agents/gemini.js +392 -0
  14. package/dist/src/agents/job-agent-assignments.js +180 -0
  15. package/dist/src/agents/lifecycle-feedback.js +147 -0
  16. package/dist/src/agents/limit-detector.js +83 -0
  17. package/dist/src/agents/opencode-launch.js +138 -0
  18. package/dist/src/agents/opencode.js +156 -0
  19. package/dist/src/agents/plan-breakdown-feedback.js +97 -0
  20. package/dist/src/agents/pool.js +168 -0
  21. package/dist/src/agents/prompt.js +462 -0
  22. package/dist/src/agents/provider-sessions.js +105 -0
  23. package/dist/src/agents/review-feedback.js +255 -0
  24. package/dist/src/agents/selection.js +113 -0
  25. package/dist/src/agents/service.js +1087 -0
  26. package/dist/src/agents/types.js +1 -0
  27. package/dist/src/agents/wave-assessment-feedback.js +69 -0
  28. package/dist/src/attention/derive.js +337 -0
  29. package/dist/src/capabilities/index.js +2 -0
  30. package/dist/src/capabilities/projection.js +183 -0
  31. package/dist/src/capabilities/types.js +1 -0
  32. package/dist/src/capabilities/validator.js +87 -0
  33. package/dist/src/cli/commands/broker-smoke.js +96 -0
  34. package/dist/src/cli/commands/broker.js +56 -0
  35. package/dist/src/cli/commands/init.js +4 -0
  36. package/dist/src/cli/commands/journal.js +43 -0
  37. package/dist/src/cli/commands/run-loop.js +56 -0
  38. package/dist/src/cli/commands/run.js +1241 -0
  39. package/dist/src/cli/commands/tui.js +187 -0
  40. package/dist/src/cli/dispatcher.js +51 -0
  41. package/dist/src/cli/errors.js +2 -0
  42. package/dist/src/cli/init.js +92 -0
  43. package/dist/src/cli/options.js +86 -0
  44. package/dist/src/cli/output.js +231 -0
  45. package/dist/src/cli/run-journal.js +342 -0
  46. package/dist/src/cli/run-types.js +1 -0
  47. package/dist/src/cli/run.js +32 -0
  48. package/dist/src/cli/runtime/dispatch-lifecycle.js +772 -0
  49. package/dist/src/cli/runtime/provider-runtime-types.js +1 -0
  50. package/dist/src/cli/runtime/provider-runtime.js +152 -0
  51. package/dist/src/cli/runtime/provider-tools.js +73 -0
  52. package/dist/src/cli/runtime/providers/antigravity.js +26 -0
  53. package/dist/src/cli/runtime/providers/claude.js +20 -0
  54. package/dist/src/cli/runtime/providers/codex.js +20 -0
  55. package/dist/src/cli/runtime/providers/gemini.js +20 -0
  56. package/dist/src/cli/runtime/providers/opencode.js +20 -0
  57. package/dist/src/cli/runtime/run-context.js +131 -0
  58. package/dist/src/cli/tui/index.js +3 -0
  59. package/dist/src/cli/tui/screen.js +388 -0
  60. package/dist/src/cli/tui/tracker.js +558 -0
  61. package/dist/src/cli/tui/types.js +1 -0
  62. package/dist/src/cli/tui/views.js +1006 -0
  63. package/dist/src/config/loader.js +136 -0
  64. package/dist/src/config/schemas.js +403 -0
  65. package/dist/src/config/types.js +1 -0
  66. package/dist/src/context/types.js +331 -0
  67. package/dist/src/domain/entities.js +1 -0
  68. package/dist/src/git/backburner-git-tool-service.js +680 -0
  69. package/dist/src/git/gitops-lifecycle.js +56 -0
  70. package/dist/src/git/merge-prep-workspace.js +357 -0
  71. package/dist/src/git/types.js +484 -0
  72. package/dist/src/github/broker-model-content.js +215 -0
  73. package/dist/src/github/broker-server.js +237 -0
  74. package/dist/src/github/broker.js +638 -0
  75. package/dist/src/github/composed.js +53 -0
  76. package/dist/src/github/gateway.js +478 -0
  77. package/dist/src/github/normalize.js +222 -0
  78. package/dist/src/github/pr-classification.js +73 -0
  79. package/dist/src/github/scoped-broker.js +35 -0
  80. package/dist/src/github/security.js +126 -0
  81. package/dist/src/github/service.js +332 -0
  82. package/dist/src/github/types.js +1 -0
  83. package/dist/src/github/utils.js +16 -0
  84. package/dist/src/journal/index.js +4 -0
  85. package/dist/src/journal/reader.js +62 -0
  86. package/dist/src/journal/renderer.js +50 -0
  87. package/dist/src/journal/service.js +72 -0
  88. package/dist/src/journal/types.js +1 -0
  89. package/dist/src/journal/writer.js +19 -0
  90. package/dist/src/mcps/bridge.js +166 -0
  91. package/dist/src/mcps/index.js +5 -0
  92. package/dist/src/mcps/reconcile.js +113 -0
  93. package/dist/src/mcps/smithery-client.js +186 -0
  94. package/dist/src/mcps/smithery.js +164 -0
  95. package/dist/src/mcps/types.js +1 -0
  96. package/dist/src/memory/json-store.js +71 -0
  97. package/dist/src/memory/prompt.js +16 -0
  98. package/dist/src/memory/scope.js +31 -0
  99. package/dist/src/memory/store.js +1 -0
  100. package/dist/src/memory/tool-service.js +142 -0
  101. package/dist/src/memory/types.js +12 -0
  102. package/dist/src/onboarding/config-writer.js +96 -0
  103. package/dist/src/onboarding/engine.js +86 -0
  104. package/dist/src/onboarding/prompt.js +102 -0
  105. package/dist/src/onboarding/services/provider-discovery.js +58 -0
  106. package/dist/src/onboarding/services/repo-discovery.js +246 -0
  107. package/dist/src/onboarding/steps/check-github-auth.js +32 -0
  108. package/dist/src/onboarding/steps/check-requirements.js +34 -0
  109. package/dist/src/onboarding/steps/configure-models.js +105 -0
  110. package/dist/src/onboarding/steps/configure-paths.js +33 -0
  111. package/dist/src/onboarding/steps/discover-providers.js +38 -0
  112. package/dist/src/onboarding/steps/discover-repos.js +39 -0
  113. package/dist/src/onboarding/steps/generate-config.js +106 -0
  114. package/dist/src/onboarding/steps/readiness-validation.js +158 -0
  115. package/dist/src/onboarding/steps/select-repos.js +76 -0
  116. package/dist/src/onboarding/steps/show-summary.js +97 -0
  117. package/dist/src/onboarding/steps/welcome.js +27 -0
  118. package/dist/src/onboarding/types.js +1 -0
  119. package/dist/src/onboarding/validators/git-access.js +63 -0
  120. package/dist/src/onboarding/validators/github-auth.js +85 -0
  121. package/dist/src/onboarding/validators/tool-checker.js +153 -0
  122. package/dist/src/onboarding/validators/workspace.js +83 -0
  123. package/dist/src/prompts/resolver.js +106 -0
  124. package/dist/src/retrospectives/candidates.js +224 -0
  125. package/dist/src/retrospectives/derive.js +169 -0
  126. package/dist/src/retrospectives/ingest.js +321 -0
  127. package/dist/src/retrospectives/management-prs.js +380 -0
  128. package/dist/src/retrospectives/proposals.js +199 -0
  129. package/dist/src/retrospectives/scopes.js +272 -0
  130. package/dist/src/retrospectives/scoring.js +171 -0
  131. package/dist/src/retrospectives/types.js +1 -0
  132. package/dist/src/state/loader.js +473 -0
  133. package/dist/src/state/types.js +15 -0
  134. package/dist/src/tasks/derivation/builders.js +70 -0
  135. package/dist/src/tasks/derivation/handlers/comment-response.js +169 -0
  136. package/dist/src/tasks/derivation/handlers/implement-plan.js +103 -0
  137. package/dist/src/tasks/derivation/handlers/index.js +54 -0
  138. package/dist/src/tasks/derivation/handlers/packet-pr-control.js +92 -0
  139. package/dist/src/tasks/derivation/handlers/packet-worktree.js +29 -0
  140. package/dist/src/tasks/derivation/handlers/plan-breakdown.js +45 -0
  141. package/dist/src/tasks/derivation/handlers/prepare-for-merge.js +91 -0
  142. package/dist/src/tasks/derivation/handlers/product-discovery.js +36 -0
  143. package/dist/src/tasks/derivation/handlers/retry-failed-task.js +125 -0
  144. package/dist/src/tasks/derivation/handlers/review-pr.js +28 -0
  145. package/dist/src/tasks/derivation/handlers/shared.js +24 -0
  146. package/dist/src/tasks/derivation/handlers/sync-parent-branch.js +100 -0
  147. package/dist/src/tasks/derivation/handlers/wave-assessment.js +223 -0
  148. package/dist/src/tasks/derivation/handlers/write-plan.js +101 -0
  149. package/dist/src/tasks/derivation/handlers/write-product-spec.js +49 -0
  150. package/dist/src/tasks/derivation/runner.js +18 -0
  151. package/dist/src/tasks/derivation/types.js +1 -0
  152. package/dist/src/tasks/derive.js +810 -0
  153. package/dist/src/tasks/mcp-skip.js +10 -0
  154. package/dist/src/tasks/retry.js +10 -0
  155. package/dist/src/tasks/task.js +184 -0
  156. package/dist/src/tasks/types.js +1 -0
  157. package/dist/src/utils/command-runner.js +192 -0
  158. package/dist/src/utils/json.js +38 -0
  159. package/dist/src/utils/logger.js +43 -0
  160. package/dist/src/utils/paths.js +38 -0
  161. package/dist/src/utils/slug.js +10 -0
  162. package/dist/src/workflows/registry.js +174 -0
  163. package/dist/src/workflows/triage.js +90 -0
  164. package/dist/src/workflows/workstream-machine/derive-events.js +121 -0
  165. package/dist/src/workflows/workstream-machine/evaluate.js +24 -0
  166. package/dist/src/workflows/workstream-machine/events.js +1 -0
  167. package/dist/src/workflows/workstream-machine/machine.js +355 -0
  168. package/dist/src/workflows/workstream-machine/selectors.js +19 -0
  169. package/dist/src/workflows/workstream-machine/types.js +1 -0
  170. package/dist/src/workstreams/branch-sync.js +87 -0
  171. package/dist/src/workstreams/derive.js +629 -0
  172. package/dist/src/workstreams/mcp-blockers.js +420 -0
  173. package/dist/src/workstreams/packet-candidates.js +42 -0
  174. package/dist/src/workstreams/packet-lifecycle-feedback.js +60 -0
  175. package/dist/src/workstreams/packet-lifecycle-report.js +199 -0
  176. package/dist/src/workstreams/packet-plan.js +597 -0
  177. package/dist/src/workstreams/packet-projections.js +190 -0
  178. package/dist/src/workstreams/parent-branch-sync-action.js +312 -0
  179. package/dist/src/workstreams/parent-branch-sync.js +148 -0
  180. package/dist/src/workstreams/phases.js +4 -0
  181. package/dist/src/workstreams/plan-breakdown-generator/export.js +19 -0
  182. package/dist/src/workstreams/plan-breakdown-generator/index.js +6 -0
  183. package/dist/src/workstreams/plan-breakdown-generator/inspect.js +50 -0
  184. package/dist/src/workstreams/plan-breakdown-generator/patch.js +139 -0
  185. package/dist/src/workstreams/plan-breakdown-generator/session.js +19 -0
  186. package/dist/src/workstreams/plan-breakdown-generator/store.js +27 -0
  187. package/dist/src/workstreams/plan-breakdown-generator/tools.js +407 -0
  188. package/dist/src/workstreams/plan-breakdown-generator/types.js +6 -0
  189. package/dist/src/workstreams/plan-breakdown-generator/validate.js +212 -0
  190. package/dist/src/workstreams/plan-breakdown-schema.js +175 -0
  191. package/dist/src/workstreams/utils.js +15 -0
  192. package/dist/src/workstreams/wave-assessment/checkpoint.js +172 -0
  193. package/dist/src/workstreams/wave-assessment/index.js +3 -0
  194. package/dist/src/workstreams/wave-assessment/session.js +84 -0
  195. package/dist/src/workstreams/wave-assessment/store.js +51 -0
  196. package/dist/src/workstreams/wave-assessment/tools.js +419 -0
  197. package/dist/src/workstreams/wave-assessment/types.js +1 -0
  198. package/dist/src/workstreams/wave-assessment/validate.js +78 -0
  199. package/dist/src/worktrees/service.js +839 -0
  200. package/dist/src/worktrees/workspace-ownership.js +34 -0
  201. package/dist/src/worktrees/workspace-recovery.js +177 -0
  202. package/package.json +61 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Elad Aviv
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 ADDED
@@ -0,0 +1,329 @@
1
+ # Backburner CLI
2
+
3
+ Backburner is a local GitHub-driven agent orchestration CLI. It uses GitHub labels, issues, and pull requests as the control plane, keeps configuration and state as readable JSON on your machine, and dispatches eligible work to provider CLIs that you already have installed locally.
4
+
5
+ Backburner currently supports:
6
+
7
+ - `backburner init` for interactive or non-interactive local setup
8
+ - `backburner run` for one orchestration cycle
9
+ - `backburner run-loop` for repeated cycles on a fixed interval
10
+ - `backburner journal` for reading persisted run and workflow events
11
+ - `backburner broker` for a local GitHub broker MCP endpoint
12
+ - a plan-first label workflow for product approval, plan approval, review requests, and parent-branch sync approval
13
+ - local provider CLIs for Antigravity, Codex, Gemini, Claude, and OpenCode
14
+
15
+ ## Prerequisites
16
+
17
+ - Node.js `>=20`
18
+ - npm
19
+ - git
20
+ - GitHub CLI authenticated for the account and repositories you want Backburner to manage:
21
+
22
+ ```sh
23
+ gh auth status
24
+ ```
25
+
26
+ - at least one supported provider CLI on `PATH`: `agy`, `codex`, `gemini`, `claude`, or `opencode`
27
+
28
+ Backburner uses your local `git`, `gh`, and provider CLI credentials. It does not provide hosted execution or cloud credentials.
29
+
30
+ ## Install
31
+
32
+ From a source checkout:
33
+
34
+ ```sh
35
+ npm install
36
+ npm run build
37
+ node dist/src/cli/run.js init
38
+ ```
39
+
40
+ Windows PowerShell:
41
+
42
+ ```powershell
43
+ npm install
44
+ npm run build
45
+ node .\dist\src\cli\run.js init
46
+ ```
47
+
48
+ For active local development, link this checkout into your global npm bin directory:
49
+
50
+ ```sh
51
+ npm run link:local
52
+ backburner init
53
+ ```
54
+
55
+ To install and verify the locally packed package:
56
+
57
+ ```sh
58
+ npm run install:local
59
+ backburner journal --json
60
+ ```
61
+
62
+ To install the local package into a temporary npm prefix:
63
+
64
+ macOS/Linux:
65
+
66
+ ```sh
67
+ npm run install:local -- --prefix /tmp/backburner-local
68
+ /tmp/backburner-local/bin/backburner journal --json
69
+ ```
70
+
71
+ Windows PowerShell:
72
+
73
+ ```powershell
74
+ npm run install:local -- --prefix "$env:TEMP\backburner-local"
75
+ & "$env:TEMP\backburner-local\backburner.cmd" journal --json
76
+ ```
77
+
78
+ Once the current package is published:
79
+
80
+ ```sh
81
+ npm install -g @backburner/cli
82
+ backburner init
83
+ ```
84
+
85
+ The package bin is `backburner`.
86
+
87
+ The npm package intentionally includes the compiled CLI under `dist/src`, `README.md`, `LICENSE`, and package metadata. Contributor docs and generated docs are kept in the source repository and are not part of the install tarball.
88
+
89
+ ## Quick Start
90
+
91
+ Run onboarding:
92
+
93
+ ```sh
94
+ backburner init
95
+ ```
96
+
97
+ Source checkout equivalent:
98
+
99
+ ```sh
100
+ node dist/src/cli/run.js init
101
+ ```
102
+
103
+ Non-interactive setup accepts defaults:
104
+
105
+ ```sh
106
+ backburner init --yes
107
+ ```
108
+
109
+ Useful `init` flags:
110
+
111
+ ```text
112
+ --code-root <path> Root where managed repos are cloned
113
+ --management-dir <path> Directory for configuration files
114
+ --outputs-dir <path> Directory for generated state, journal, and logs
115
+ --log-dir <path> Directory for execution logs
116
+ --workspaces-dir <path> Directory used by onboarding readiness checks
117
+ --yes, -y Accept defaults without prompts
118
+ ```
119
+
120
+ `backburner init` checks local requirements, confirms `gh auth status`, discovers repositories, detects provider CLIs, and writes these files into the management directory:
121
+
122
+ - `repos.json`
123
+ - `agents.json`
124
+
125
+ If either file already exists, onboarding asks before overwriting it. With `--yes`, defaults are accepted non-interactively.
126
+
127
+ ## Default Directories
128
+
129
+ By default, Backburner stores data under `~/.backburner`:
130
+
131
+ - code root: `~/.backburner/code`
132
+ - management directory: `~/.backburner/management`
133
+ - outputs directory: `~/.backburner/outputs`
134
+ - state directory: `~/.backburner/outputs/state`
135
+ - journal directory: `~/.backburner/outputs/journal`
136
+ - log directory: `~/.backburner/outputs/logs`
137
+ - onboarding workspaces directory: `<code-root>/_worktrees`
138
+
139
+ Set `BACKBURNER_ROOT` to change the root used for the default code, management, and outputs directories.
140
+
141
+ ## Configuration
142
+
143
+ Backburner configuration lives in the management directory.
144
+
145
+ Minimal `repos.json`:
146
+
147
+ ```json
148
+ {
149
+ "allowedUsers": [
150
+ "your-github-user"
151
+ ],
152
+ "repos": [
153
+ {
154
+ "id": "your-github-user-example-repo",
155
+ "owner": "your-github-user",
156
+ "name": "example-repo",
157
+ "defaultBranch": "main",
158
+ "localPath": "your-github-user/example-repo",
159
+ "enabled": true,
160
+ "labels": {
161
+ "agentInProgress": "agent-in-progress",
162
+ "agentProductApproved": "agent-product-approved",
163
+ "agentPlanApproved": "agent-plan-approved",
164
+ "agentReview": "agent-review",
165
+ "planBreakdownNeeded": "plan-breakdown-needed",
166
+ "agentSyncParentBranch": "agent-sync-parent-branch",
167
+ "prepareForMerge": "prepare-for-merge"
168
+ }
169
+ }
170
+ ]
171
+ }
172
+ ```
173
+
174
+ Minimal `agents.json`:
175
+
176
+ ```json
177
+ {
178
+ "agents": [
179
+ {
180
+ "id": "codex-strong",
181
+ "provider": "codex",
182
+ "modelClass": "strong",
183
+ "model": "gpt-5",
184
+ "roles": [
185
+ "product",
186
+ "planning",
187
+ "review",
188
+ "discussion",
189
+ "implementation_manager"
190
+ ],
191
+ "command": "codex",
192
+ "enabled": true
193
+ },
194
+ {
195
+ "id": "opencode-cheap",
196
+ "provider": "opencode",
197
+ "modelClass": "cheap",
198
+ "model": "your-fast-model",
199
+ "roles": [
200
+ "implementation",
201
+ "discussion"
202
+ ],
203
+ "command": "opencode",
204
+ "enabled": true
205
+ }
206
+ ]
207
+ }
208
+ ```
209
+
210
+ `allowedUsers` limits which GitHub users can feed issues, comments, reviews, and pull requests into task derivation. `localPath` must be relative to `--code-root`.
211
+
212
+ Agent selection filters enabled agents by required role and `modelClass`, then breaks ties by lowest agent `id`. Provider model names are passed through to the provider CLI and are not validated against vendor catalogs.
213
+
214
+ ## Label Control Plane
215
+
216
+ Configure labels per repository in `repos.json`. The common defaults are:
217
+
218
+ - `agent-product-approved`: approves product discovery and allows Backburner to create the implementation PR/worktree flow for an issue
219
+ - `agent-plan-approved`: approves an implementation plan and allows implementation tasks to run
220
+ - `agent-review`: requests an explicit code review; review tasks are dispatched when the PR has this label and its head SHA changed since the last review
221
+ - `agent-sync-parent-branch`: authorizes Backburner to sync a blocked parent implementation branch from the repository default branch
222
+
223
+ Backburner also uses `agent-in-progress`, `plan-breakdown-needed`, and `prepare-for-merge` when those labels are configured.
224
+
225
+ ## Commands
226
+
227
+ Run one cycle:
228
+
229
+ ```sh
230
+ backburner run
231
+ ```
232
+
233
+ Source checkout:
234
+
235
+ ```sh
236
+ node dist/src/cli/run.js run
237
+ ```
238
+
239
+ Common run flags:
240
+
241
+ ```text
242
+ --code-root <path>
243
+ --management-dir <path>
244
+ --outputs-dir <path>
245
+ --log-dir <path>
246
+ --broker-port <port>
247
+ --headless
248
+ --once
249
+ ```
250
+
251
+ Run continuously:
252
+
253
+ ```sh
254
+ backburner run-loop --interval-minutes 5
255
+ ```
256
+
257
+ `run-loop` accepts the same path and broker flags as `run`, plus either `--interval-seconds <seconds>` or `--interval-minutes <minutes>`. The default interval is 5 minutes. `SIGINT` and `SIGTERM` request a graceful stop after the current cycle.
258
+
259
+ Read the journal:
260
+
261
+ ```sh
262
+ backburner journal --last 20
263
+ backburner journal --repo your-github-user-example-repo --json
264
+ ```
265
+
266
+ Journal filters:
267
+
268
+ ```text
269
+ --outputs-dir <path>
270
+ --repo <id>
271
+ --workstream <id>
272
+ --issue <number>
273
+ --pr <number>
274
+ --since <ISO timestamp>
275
+ --last <number>
276
+ --json
277
+ --verbose
278
+ ```
279
+
280
+ Start the GitHub broker MCP:
281
+
282
+ ```sh
283
+ backburner broker --port 4444
284
+ ```
285
+
286
+ Broker flags:
287
+
288
+ ```text
289
+ --management-dir <path>
290
+ --host <host>
291
+ --port <port>
292
+ ```
293
+
294
+ The broker serves:
295
+
296
+ - `POST /mcp`
297
+ - `GET /health`
298
+
299
+ It exposes managed-repository tools for issue, PR, comment, check-run, code-search, PR creation, and PR review-comment reply workflows, plus plan-breakdown and wave-assessment tools used by Backburner providers.
300
+
301
+ Smoke-test the broker after building:
302
+
303
+ ```sh
304
+ npm run smoke:github-broker
305
+ npm run smoke:github-broker -- --repo your-github-user/example-repo --issue-number 123
306
+ ```
307
+
308
+ ## What A Run Does
309
+
310
+ `backburner run` loads configuration, prepares local management and outputs directories, loads state, syncs enabled repositories, scans GitHub through `gh`, derives tasks, starts a local GitHub broker for provider access, dispatches eligible tasks to configured provider CLIs, writes state and logs, and prints a run summary.
311
+
312
+ Generated files are readable JSON. Control-plane state is written under `<outputs-dir>/state`, including repository sync status, issues, PRs, comments, tasks, worktrees, attention records, MCP status, provider limits, and job memory. Execution logs and artifacts are written under `<outputs-dir>/logs`. Journal events are written under `<outputs-dir>/journal`.
313
+
314
+ ## Platform Support
315
+
316
+ Backburner is intended to run on macOS, Linux, and Windows with Node.js 20 or newer. The current CI workflow in this checkout runs on Ubuntu, macOS, and Windows with Node 20 and 22, and includes build, typecheck, tests, package dry-run, and local package install smoke checks.
317
+
318
+ ## Verification
319
+
320
+ Use these checks before publishing or changing behavior:
321
+
322
+ ```sh
323
+ npm run build
324
+ npm run typecheck
325
+ npm test
326
+ npm pack --dry-run
327
+ ```
328
+
329
+ For docs-only changes, at minimum verify that documented commands, package contents, and public-safety scrub patterns still match the repository.
@@ -0,0 +1,162 @@
1
+ import { copyFile, mkdir, readFile } from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ import { writeJsonFileAtomic } from "../utils/json.js";
4
+ export function mapPermissionToAntigravityMode(permission) {
5
+ switch (permission) {
6
+ case "read-only":
7
+ return "sandbox";
8
+ case "workspace-write":
9
+ return "always-proceed";
10
+ }
11
+ }
12
+ export function buildAntigravityCliArgs(options) {
13
+ const args = [
14
+ "--print-timeout",
15
+ options.printTimeout,
16
+ "--log-file",
17
+ options.logFilePath
18
+ ];
19
+ if (options.model) {
20
+ args.push("--model", options.model);
21
+ }
22
+ if (options.conversationId) {
23
+ args.push("--conversation", options.conversationId);
24
+ }
25
+ if (options.permissionMode === "sandbox") {
26
+ args.push("--sandbox");
27
+ }
28
+ else {
29
+ args.push("--dangerously-skip-permissions");
30
+ }
31
+ args.push("--print", "-");
32
+ return args;
33
+ }
34
+ export async function writeAntigravitySettings(settingsPath, options) {
35
+ await writeJsonFileAtomic(settingsPath, {
36
+ allowNonWorkspaceAccess: false,
37
+ enableTerminalSandbox: options.permissionMode === "sandbox",
38
+ toolPermission: options.permissionMode === "sandbox" ? "proceed-in-sandbox" : "always-proceed",
39
+ trustedWorkspaces: [options.cwd],
40
+ ...(options.model ? { model: options.model } : {})
41
+ });
42
+ }
43
+ export async function writeAntigravityMcpConfig(configPath, options) {
44
+ const config = options.mcp ? buildMcpConfig(options.mcp) : { mcpServers: {} };
45
+ await writeJsonFileAtomic(configPath, config);
46
+ }
47
+ export async function ensureAntigravityMcpConfig(antigravityHome, mcp, options = {}) {
48
+ const configPath = path.join(antigravityHome, "mcp_config.json");
49
+ await mkdir(antigravityHome, { recursive: true });
50
+ const existing = await readExistingMcpConfig(configPath);
51
+ const config = existing.config;
52
+ const mcpServers = normalizeMcpServers(config["mcpServers"]);
53
+ const existingServer = normalizeServerRecord(mcpServers[mcp.serverName]);
54
+ const configuredUrl = getConfiguredServerUrl(existingServer);
55
+ if (configuredUrl === mcp.serverUrl) {
56
+ return { configPath, changed: false };
57
+ }
58
+ let backupPath;
59
+ if (existing.existed) {
60
+ backupPath = `${configPath}.backup-before-backburner-${formatBackupTimestamp(options.now?.() ?? new Date().toISOString())}`;
61
+ await copyFile(configPath, backupPath);
62
+ }
63
+ const nextConfig = {
64
+ ...config,
65
+ mcpServers: {
66
+ ...mcpServers,
67
+ [mcp.serverName]: {
68
+ ...existingServer,
69
+ serverUrl: mcp.serverUrl
70
+ }
71
+ }
72
+ };
73
+ await writeJsonFileAtomic(configPath, nextConfig);
74
+ return {
75
+ configPath,
76
+ changed: true,
77
+ ...(backupPath ? { backupPath } : {})
78
+ };
79
+ }
80
+ function buildMcpConfig(mcp) {
81
+ return {
82
+ mcpServers: {
83
+ [mcp.serverName]: {
84
+ serverUrl: mcp.serverUrl
85
+ }
86
+ }
87
+ };
88
+ }
89
+ async function readExistingMcpConfig(configPath) {
90
+ let raw;
91
+ try {
92
+ raw = await readFile(configPath, "utf8");
93
+ }
94
+ catch (err) {
95
+ if (err instanceof Error && "code" in err && err.code === "ENOENT") {
96
+ return { existed: false, config: {} };
97
+ }
98
+ throw err;
99
+ }
100
+ let parsed;
101
+ try {
102
+ parsed = JSON.parse(raw);
103
+ }
104
+ catch (err) {
105
+ throw new Error(`Antigravity MCP config at ${configPath} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);
106
+ }
107
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
108
+ throw new Error(`Antigravity MCP config at ${configPath} must be a JSON object.`);
109
+ }
110
+ return { existed: true, config: parsed };
111
+ }
112
+ function normalizeMcpServers(value) {
113
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
114
+ return {};
115
+ }
116
+ return value;
117
+ }
118
+ function normalizeServerRecord(value) {
119
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
120
+ return {};
121
+ }
122
+ return value;
123
+ }
124
+ function getConfiguredServerUrl(serverRecord) {
125
+ return typeof serverRecord["serverUrl"] === "string"
126
+ ? serverRecord["serverUrl"]
127
+ : typeof serverRecord["url"] === "string"
128
+ ? serverRecord["url"]
129
+ : undefined;
130
+ }
131
+ function formatBackupTimestamp(timestamp) {
132
+ return timestamp.replace(/[^0-9A-Za-z_-]+/g, "-");
133
+ }
134
+ export function getAntigravityEnvOverrides() {
135
+ return {
136
+ AGY_HOME: undefined,
137
+ ANTIGRAVITY_HOME: undefined
138
+ };
139
+ }
140
+ export function buildGlobalAntigravityLaunchInstructions(input) {
141
+ return [
142
+ "# Global Antigravity Instructions",
143
+ "",
144
+ "These instructions apply across repositories for this orchestrated run.",
145
+ "",
146
+ "## MCP Server",
147
+ `Use the local MCP server \`${input.mcp.serverName}\` for managed GitHub operations.`,
148
+ "- Invoke broker tools instead of using `gh` directly.",
149
+ "- If a needed GitHub capability is missing from the broker, report the gap clearly instead of silently bypassing it.",
150
+ "",
151
+ "Enabled broker tools for this run:",
152
+ ...input.mcp.toolAllowList.map((tool) => `- \`${tool}\``),
153
+ "",
154
+ "Any GitHub-authored message you post must begin with `🤖`."
155
+ ].join("\n");
156
+ }
157
+ export function prependGlobalAntigravityLaunchInstructions(promptText, options) {
158
+ if (!options.mcp) {
159
+ return promptText;
160
+ }
161
+ return `${buildGlobalAntigravityLaunchInstructions({ mcp: options.mcp })}\n\n${promptText}`;
162
+ }