breakaway 1.0.2-main.5 → 1.0.2-main.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "breakaway",
3
- "version": "1.0.2-main.5",
3
+ "version": "1.0.2-main.7",
4
4
  "description": "The task board for you and your coding agents: a Cloudflare Worker, its web app, Taskwarrior sync, and the CLI (npx breakaway).",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "type": "module",
@@ -7,6 +7,7 @@ import { CLI_PACKAGE } from './init.js';
7
7
  /** The subcommands each command knows. Without one, each lists or shows (horizon needs close). */
8
8
  export const SUBCOMMANDS = {
9
9
  agents: ['next', 'start', 'refine'],
10
+ github: ['fix', 'review'],
10
11
  repos: ['add', 'init', 'modify', 'remove', 'setup'],
11
12
  routines: ['add', 'modify', 'run', 'trigger', 'revoke', 'pause', 'resume'],
12
13
  horizon: ['close'],
@@ -18,7 +19,6 @@ export const NO_ARGUMENTS = new Set([
18
19
  'list',
19
20
  'next',
20
21
  'activity',
21
- 'github',
22
22
  'health',
23
23
  'connections',
24
24
  'export',
@@ -74,6 +74,45 @@ export function githubRequest(repo, { sync = false } = {}) {
74
74
  return ['GET', repo ? `github?repo=${encodeURIComponent(repo)}` : 'github', undefined];
75
75
  }
76
76
 
77
+ /** What `github fix` accepts for --problem: the same three the pull request page offers. */
78
+ export const FIX_PROBLEMS = ['conflicts', 'failing', 'review'];
79
+
80
+ /**
81
+ * The request behind `npx breakaway github fix <n>` and `github review <n>` (BRK-81): the pull request page's "Fix with an
82
+ * agent" and "Safe to merge?" buttons (`POST github/pulls/<n>/fix` and `/review`). It names the checkout's repository
83
+ * like `github` does. Returns an error message instead when the number or `problem` can't be right.
84
+ * @param {'fix' | 'review'} action
85
+ * @param {string | number | undefined} number
86
+ * @param {{ repo?: string | null, problem?: string, note?: string }} [options]
87
+ * @returns {{ error?: string, request?: [string, string, Record<string, string>] }}
88
+ */
89
+ export function pullAgentRequest(action, number, { repo = null, problem, note } = {}) {
90
+ const n = String(number ?? '').replace(/^#/u, '');
91
+ if (!/^[1-9]\d{0,8}$/u.test(n)) return { error: `say which pull request: npx breakaway github ${action} <number>` };
92
+ if (problem !== undefined && action !== 'fix') return { error: '--problem is for github fix' };
93
+ if (problem !== undefined && !FIX_PROBLEMS.includes(problem))
94
+ return { error: `--problem is ${FIX_PROBLEMS.join(', ')}` };
95
+ const body = {
96
+ ...(repo ? { repo } : {}),
97
+ ...(problem ? { problem } : {}),
98
+ ...(typeof note === 'string' && note.trim() ? { note } : {}),
99
+ };
100
+ return { request: ['POST', `github/pulls/${n}/${action}`, body] };
101
+ }
102
+
103
+ /**
104
+ * What the CLI says about an answer to those requests: which task and agent took the pull request, or who already has it.
105
+ * @param {'fix' | 'review'} action
106
+ * @param {string | number} number
107
+ * @param {{ task: { wid?: string, short?: string }, run?: { url?: string, agent?: string } | null, already?: string | null }} answer
108
+ */
109
+ export function pullAgentSummary(action, number, { task, run, already }) {
110
+ const id = task.wid ?? task.short;
111
+ if (!run) return `${id} already has it: ${already}.`;
112
+ const what = action === 'fix' ? `fixing #${number}` : `testing #${number}`;
113
+ return `Started ${run.agent ? `${run.agent}, ` : 'an agent '}${what} on ${id}${run.url ? `: ${run.url}` : ''}`;
114
+ }
115
+
77
116
  /**
78
117
  * The task an idea becomes (`npx breakaway idea`): its first line, kept short, as the title, and the whole text as its
79
118
  * description. Like `add`, it lands in the repository of the checkout it was written in (BRK-71): without one, the
package/scripts/tasks.mjs CHANGED
@@ -44,7 +44,14 @@ import { sessionProxy, routeThroughSessionProxy } from './tasks/proxy.js';
44
44
  import { githubFromRemote, inRepo, pickRepo } from './tasks/repo.js';
45
45
  import { NO_TERMINAL, ask as askIn } from './tasks/ask.js';
46
46
  import { CLI_PACKAGE, PROMPT_SECTIONS, initPlan, machineTaskrc, promptSections } from './tasks/init.js';
47
- import { githubRequest, ideaTask, staleCliWarning, unknownSubcommand } from './tasks/cli.js';
47
+ import {
48
+ githubRequest,
49
+ ideaTask,
50
+ pullAgentRequest,
51
+ pullAgentSummary,
52
+ staleCliWarning,
53
+ unknownSubcommand,
54
+ } from './tasks/cli.js';
48
55
  import { CLI_VERSION } from '../src/cli-version.js';
49
56
  import { LEGACY, parseInstall, secretName } from '../src/install.js';
50
57
  import {
@@ -143,6 +150,8 @@ Reading (list, next, claim, and add work in this checkout's repos
143
150
  routines saved prompts the owner runs with a button, and their caps
144
151
  routines run <slug> run one now: makes a RUN task and starts an agent on it [--note <text>]
145
152
  horizon close close now: finished tasks go to the archive, next becomes now, later becomes next [--dry-run]
153
+ github fix <n> start an agent on a pull request's conflicts, failing checks, or review comments (owner) [--problem conflicts|failing|review] [--note <text>] [--repo <slug>]
154
+ github review <n> start an agent that tests a Dependabot pull request, as Safe to merge? does (owner) [--note <text>] [--repo <slug>]
146
155
  github the checkout's repository on GitHub: open pull requests, checks, reviews, CI, deploys, alerts [--sync] [--repo <slug>]
147
156
  hook session|wait the Claude Code session hooks a repository's .claude/settings.json runs (npx breakaway hook session)
148
157
  health the server's state
@@ -1188,6 +1197,18 @@ const commands = {
1188
1197
  );
1189
1198
  },
1190
1199
  async github() {
1200
+ const action = args[0];
1201
+ if (action === 'fix' || action === 'review') {
1202
+ const built = pullAgentRequest(action, args[1], {
1203
+ repo: (await checkoutRepo()).slug,
1204
+ problem: opts.problem,
1205
+ note: opts.note,
1206
+ });
1207
+ if (built.error || !built.request) fail(built.error ?? 'bad request');
1208
+ const answer = await call(...built.request);
1209
+ print(answer, (a) => pullAgentSummary(action, args[1].replace(/^#/u, ''), a));
1210
+ return;
1211
+ }
1191
1212
  const g = await call(...githubRequest((await checkoutRepo()).slug, { sync: Boolean(opts.sync) }));
1192
1213
  print(g, (d) => {
1193
1214
  if (!d.connected) return "GitHub isn't connected yet: open the GitHub view on the board (docs/tasks.md#github).";
@@ -5,5 +5,5 @@
5
5
  * bump CLI_VERSION and set CLI_FINGERPRINT to the value it prints. Constants only: the board's Worker imports it,
6
6
  * so it lives in the board's package (CLD-135) and the CLI imports it from here.
7
7
  */
8
- export const CLI_VERSION = 38;
9
- export const CLI_FINGERPRINT = 'e5cf577cb5354653';
8
+ export const CLI_VERSION = 39;
9
+ export const CLI_FINGERPRINT = '15250a95aca206af';