@bradtaylorsf/alpha-loop 1.15.0 → 1.15.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"roadmap.js","sourceRoot":"","sources":["../../src/commands/roadmap.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,0BAA0B,EAC1B,oBAAoB,GAGrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAO1B,iEAAiE;AACjE,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAuB;IAC1D,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEtD,8EAA8E;IAC9E,GAAG,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAE3C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,GAAG,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,MAAM,gBAAgB,CAAC,CAAC;IAEjD,6EAA6E;IAC7E,GAAG,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAC5C,MAAM,kBAAkB,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACvD,GAAG,CAAC,IAAI,CAAC,SAAS,kBAAkB,CAAC,MAAM,wBAAwB,CAAC,CAAC;IAErE,wDAAwD;IACxD,8EAA8E;IAC9E,sFAAsF;IAEtF,wBAAwB;IACxB,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7C,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,cAAc;YACtC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,KAAK;YAC7C,CAAC,CAAC,KAAK,CAAC,IAAI;QACd,SAAS,EAAE,IAAqB;KACjC,CAAC,CAAC,CAAC;IAEJ,8EAA8E;IAC9E,MAAM,GAAG,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAEzC,8EAA8E;IAC9E,GAAG,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IAC7C,MAAM,aAAa,GAAG,kBAAkB,CAAC;QACvC,MAAM,EAAE,eAAe;QACvB,UAAU,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACzC,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,KAAK,EAAE,CAAC,CAAC,KAAK;SACf,CAAC,CAAC;QACH,cAAc,EAAE,GAAG,CAAC,cAAc;QAClC,aAAa,EAAE,GAAG,CAAC,aAAa;KACjC,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC9D,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,qBAAqB,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACrE,aAAa,CAAC,UAAU,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;IAClD,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CACX,GAAG,QAAQ,OAAO,UAAU,eAAe,EAC3C,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,CAChD,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,yBAAyB,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACnD,GAAG,CAAC,KAAK,CAAC,0EAA0E,CAAC,CAAC;QACtF,IAAI,MAAM,CAAC,MAAM;YAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC1D,OAAO;IACT,CAAC;IAED,IAAI,MAA4E,CAAC;IACjF,IAAI,CAAC;QACH,MAAM,GAAG,uBAAuB,CAAuE,MAAM,CAAC,MAAM,CAAC,CAAC;IACxH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,CAAC,iCAAkC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACrE,GAAG,CAAC,KAAK,CAAC,qCAAqC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9E,OAAO;IACT,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjF,GAAG,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QACnD,OAAO;IACT,CAAC;IAED,iEAAiE;IACjE,MAAM,iBAAiB,GAAG,0BAA0B,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;IAC5F,MAAM,CAAC,UAAU,GAAG,iBAAiB,CAAC,UAAU,CAAC;IACjD,MAAM,CAAC,WAAW,GAAG,iBAAiB,CAAC,WAAW,CAAC;IAEnD,8EAA8E;IAC9E,MAAM,cAAc,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC;IACvF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,aAAa,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACzF,GAAG,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,MAAM,sBAAsB,MAAM,CAAC,WAAW,CAAC,MAAM,gBAAgB,CAAC,CAAC;IAEjG,8EAA8E;IAC9E,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,GAAG,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,8EAA8E;IAC9E,IAAI,YAAsB,CAAC;IAE3B,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,YAAY,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACnF,GAAG,CAAC,IAAI,CAAC,uBAAuB,YAAY,CAAC,MAAM,0BAA0B,CAAC,CAAC;IACjF,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC3C,MAAM,OAAO,GAAG,CAAC,CAAC,gBAAgB,IAAI,YAAY,CAAC;YACnD,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,SAAS,gBAAgB,OAAO,GAAG;gBAC1E,KAAK,EAAE,CAAC,CAAC,QAAQ;gBACjB,OAAO,EAAE,CAAC,CAAC,QAAQ;aACpB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,YAAY,GAAG,MAAM,QAAQ,CAAC;YAC5B,OAAO,EAAE,8BAA8B;YACvC,OAAO;SACR,CAAC,CAAC;QAEH,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,GAAG,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YACrC,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC;YAC5B,OAAO,EAAE,UAAU,aAAa,CAAC,MAAM,4BAA4B,YAAY,CAAC,MAAM,YAAY;SACnG,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACvB,OAAO;QACT,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,qDAAqD;IACrD,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAC;IAElD,oCAAoC;IACpC,KAAK,MAAM,CAAC,IAAI,kBAAkB,EAAE,CAAC;QACnC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,wBAAwB;IACxB,IAAI,iBAAiB,GAAG,CAAC,CAAC;IAC1B,KAAK,MAAM,EAAE,IAAI,aAAa,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC;YAC1F,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;gBACZ,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBACnC,iBAAiB,EAAE,CAAC;gBACpB,GAAG,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,KAAK,wBAAwB,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,KAAK,MAAO,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,8BAA8B;IAC9B,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QAC5C,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,SAAS;QAE1D,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/C,QAAQ,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,QAAQ,gBAAgB,UAAU,CAAC,SAAS,aAAa,CAAC,CAAC;YACxF,SAAS;QACX,CAAC;QAED,IAAI,CAAC;YACH,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;YAC1E,QAAQ,EAAE,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,QAAQ,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,sDAAsD;IACtD,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;QACvB,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YAC5C,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAC1D,IAAI,CAAC;gBACH,iBAAiB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;YACxF,CAAC;YAAC,MAAM,CAAC;gBACP,mCAAmC;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,GAAG,CAAC,OAAO,CAAC,WAAW,iBAAiB,2BAA2B,QAAQ,WAAW,CAAC,CAAC;IAExF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,GAAG,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,uBAAuB,CAAC,CAAC;QACpD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"roadmap.js","sourceRoot":"","sources":["../../src/commands/roadmap.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { type Milestone, type Issue } from '../lib/github.js';
1
2
  export type RunOptions = {
2
3
  dryRun?: boolean;
3
4
  model?: string;
@@ -23,12 +24,15 @@ export type PickTargetResult = {
23
24
  type: 'epic';
24
25
  epicNum: number;
25
26
  epicTitle: string;
27
+ epic: Issue;
26
28
  } | {
27
29
  type: 'milestone';
28
30
  title: string;
29
31
  } | {
30
32
  type: 'all';
31
33
  };
34
+ export declare function formatEpicPickerMeta(epic: Issue): string;
35
+ export declare function formatMilestonePickerMeta(milestone: Milestone, epics: Issue[]): string;
32
36
  /**
33
37
  * Run the main loop: poll for issues, process them, finalize session.
34
38
  */
@@ -7,7 +7,7 @@ import { log } from '../lib/logger.js';
7
7
  import { exec } from '../lib/shell.js';
8
8
  import { loadConfig, assertSafeShellArg } from '../lib/config.js';
9
9
  import { pollIssues, listMilestones, listEpics, getEpicSubIssues, getIssueWithComments, getMergedPRForIssue, updateEpicChecklist, commentIssue, closeIssue, labelIssue, } from '../lib/github.js';
10
- import { buildEpicSummary } from '../lib/epics.js';
10
+ import { buildEpicSummary, parseSubIssues } from '../lib/epics.js';
11
11
  import { verifyEpic } from '../lib/verify-epic.js';
12
12
  import { processIssue, processBatch } from '../lib/pipeline.js';
13
13
  import { createSession, finalizeSession } from '../lib/session.js';
@@ -118,6 +118,28 @@ function askChoice(prompt, max) {
118
118
  });
119
119
  });
120
120
  }
121
+ function hasEpicLabel(issue) {
122
+ return issue.labels.some((label) => label.toLowerCase() === 'epic');
123
+ }
124
+ export function formatEpicPickerMeta(epic) {
125
+ const summary = buildEpicSummary(epic);
126
+ const progress = summary.totalCount > 0
127
+ ? `${summary.doneCount}/${summary.totalCount} done`
128
+ : 'no sub-issues';
129
+ const milestone = epic.milestone ? ` · milestone ${epic.milestone}` : '';
130
+ return `${progress}${milestone}`;
131
+ }
132
+ export function formatMilestonePickerMeta(milestone, epics) {
133
+ const progress = milestone.openIssues + milestone.closedIssues > 0
134
+ ? `${milestone.closedIssues}/${milestone.openIssues + milestone.closedIssues} done`
135
+ : 'empty';
136
+ const due = milestone.dueOn ? ` · due ${milestone.dueOn.split('T')[0]}` : '';
137
+ const scheduledEpicCount = epics.filter((epic) => epic.milestone === milestone.title).length;
138
+ const scheduled = scheduledEpicCount > 0
139
+ ? ` · ${scheduledEpicCount} scheduled epic${scheduledEpicCount === 1 ? '' : 's'}`
140
+ : '';
141
+ return `${milestone.openIssues} open, ${progress}${due}${scheduled}`;
142
+ }
121
143
  /**
122
144
  * Show open epics + milestones and let the user pick one, or choose "all in order".
123
145
  * Epics are listed first (they're typically what the user actually wants).
@@ -140,7 +162,7 @@ async function pickTarget(repo, opts) {
140
162
  if (opts.preferEpics && epics.length === 1) {
141
163
  const only = epics[0];
142
164
  log.info(`preferEpics: auto-selecting sole open epic #${only.number}`);
143
- return { type: 'epic', epicNum: only.number, epicTitle: only.title };
165
+ return { type: 'epic', epicNum: only.number, epicTitle: only.title, epic: only };
144
166
  }
145
167
  const BOLD = '\x1b[1m';
146
168
  const DIM = '\x1b[2m';
@@ -151,11 +173,7 @@ async function pickTarget(repo, opts) {
151
173
  console.error('');
152
174
  for (let i = 0; i < epics.length; i++) {
153
175
  const e = epics[i];
154
- const summary = buildEpicSummary(e);
155
- const progress = summary.totalCount > 0
156
- ? `${summary.doneCount}/${summary.totalCount} done`
157
- : 'no sub-issues';
158
- console.error(` ${BOLD}${i + 1}${NC} ${e.title} #${e.number} ${DIM}(${progress})${NC}`);
176
+ console.error(` ${BOLD}${i + 1}${NC} ${e.title} #${e.number} ${DIM}(${formatEpicPickerMeta(e)})${NC}`);
159
177
  }
160
178
  console.error('');
161
179
  }
@@ -164,11 +182,7 @@ async function pickTarget(repo, opts) {
164
182
  console.error('');
165
183
  for (let i = 0; i < milestones.length; i++) {
166
184
  const m = milestones[i];
167
- const progress = m.openIssues + m.closedIssues > 0
168
- ? `${m.closedIssues}/${m.openIssues + m.closedIssues} done`
169
- : 'empty';
170
- const due = m.dueOn ? ` · due ${m.dueOn.split('T')[0]}` : '';
171
- console.error(` ${BOLD}${epics.length + i + 1}${NC} ${m.title} ${DIM}(${m.openIssues} open, ${progress}${due})${NC}`);
185
+ console.error(` ${BOLD}${epics.length + i + 1}${NC} ${m.title} ${DIM}(${formatMilestonePickerMeta(m, epics)})${NC}`);
172
186
  }
173
187
  console.error('');
174
188
  }
@@ -183,13 +197,83 @@ async function pickTarget(repo, opts) {
183
197
  if (choice <= epics.length) {
184
198
  const selected = epics[choice - 1];
185
199
  log.success(`Epic selected: ${selected.title} (#${selected.number})`);
186
- return { type: 'epic', epicNum: selected.number, epicTitle: selected.title };
200
+ return { type: 'epic', epicNum: selected.number, epicTitle: selected.title, epic: selected };
187
201
  }
188
202
  const milestoneIdx = choice - epics.length - 1;
189
203
  const selected = milestones[milestoneIdx];
190
204
  log.success(`Milestone selected: ${selected.title} (${selected.openIssues} open issues)`);
191
205
  return { type: 'milestone', title: selected.title };
192
206
  }
207
+ async function resolveRunTarget(config, options) {
208
+ let activeMilestone = config.milestone;
209
+ // --epic <N> overrides everything except --verify-only
210
+ if (options.epic !== undefined) {
211
+ if (typeof options.epic !== 'number' || !Number.isFinite(options.epic) || options.epic <= 0) {
212
+ log.error('--epic requires a positive integer issue number (e.g. --epic 165)');
213
+ process.exit(1);
214
+ return null;
215
+ }
216
+ const epic = getIssueWithComments(config.repo, options.epic);
217
+ if (!epic) {
218
+ log.error(`Could not fetch epic #${options.epic}`);
219
+ process.exit(1);
220
+ return null;
221
+ }
222
+ if (!hasEpicLabel(epic)) {
223
+ log.error(`Issue #${options.epic} is not labeled 'epic'. Add the epic label before running --epic.`);
224
+ process.exit(1);
225
+ return null;
226
+ }
227
+ return {
228
+ activeEpic: epic.number,
229
+ activeEpicTitle: epic.title,
230
+ activeEpicIssue: epic,
231
+ activeMilestone: '',
232
+ };
233
+ }
234
+ if (activeMilestone && options.skipEpic !== true) {
235
+ const scheduledEpics = listEpics(config.repo, { milestone: activeMilestone });
236
+ if (scheduledEpics.length === 1) {
237
+ const epic = scheduledEpics[0];
238
+ log.info(`Milestone '${activeMilestone}' has one scheduled epic; processing epic #${epic.number}: ${epic.title}`);
239
+ return {
240
+ activeEpic: epic.number,
241
+ activeEpicTitle: epic.title,
242
+ activeEpicIssue: epic,
243
+ activeMilestone: '',
244
+ };
245
+ }
246
+ if (scheduledEpics.length > 1) {
247
+ log.error(`Milestone '${activeMilestone}' has multiple scheduled epics:`);
248
+ for (const epic of scheduledEpics) {
249
+ log.error(` #${epic.number} ${epic.title}`);
250
+ }
251
+ log.error(`Use --epic <N> to choose one, or --skip-epic --milestone ${JSON.stringify(activeMilestone)} to process flat issues.`);
252
+ process.exit(1);
253
+ return null;
254
+ }
255
+ log.info(`No open epics scheduled for milestone '${activeMilestone}' — using flat milestone issue flow`);
256
+ }
257
+ // Interactive picker when TTY and nothing preset
258
+ if (!activeMilestone && !config.dryRun && process.stdin.isTTY) {
259
+ const target = await pickTarget(config.repo, {
260
+ preferEpics: config.preferEpics,
261
+ hideEpics: options.skipEpic === true,
262
+ });
263
+ if (target.type === 'epic') {
264
+ return {
265
+ activeEpic: target.epicNum,
266
+ activeEpicTitle: target.epicTitle,
267
+ activeEpicIssue: target.epic,
268
+ activeMilestone: '',
269
+ };
270
+ }
271
+ if (target.type === 'milestone') {
272
+ activeMilestone = target.title;
273
+ }
274
+ }
275
+ return { activeMilestone };
276
+ }
193
277
  /**
194
278
  * Run the verification pass on an epic: fetch sub-issues + merged PRs, evaluate
195
279
  * AC via the review model, post a summary comment, and close the epic on pass
@@ -203,6 +287,11 @@ async function runEpicVerificationFlow(epicNum, config, session) {
203
287
  log.error(`Could not fetch epic #${epicNum}`);
204
288
  return;
205
289
  }
290
+ if (!hasEpicLabel(epic)) {
291
+ log.error(`Issue #${epicNum} is not labeled 'epic'. Add the epic label before running epic verification.`);
292
+ process.exit(1);
293
+ return;
294
+ }
206
295
  const refs = getEpicSubIssues(config.repo, epicNum);
207
296
  if (refs.length === 0) {
208
297
  log.warn(`Epic #${epicNum} has no sub-issues in its checklist — nothing to verify`);
@@ -239,6 +328,108 @@ async function runEpicVerificationFlow(epicNum, config, session) {
239
328
  log.warn(`Epic #${epicNum} needs human review: verdict=${result.verdict}`);
240
329
  }
241
330
  }
331
+ const MAX_EPIC_BODY_SUMMARY_CHARS = 1200;
332
+ function extractChecklistTitle(line, issueNum) {
333
+ const marker = `#${issueNum}`;
334
+ const idx = line.indexOf(marker);
335
+ if (idx === -1)
336
+ return undefined;
337
+ const suffix = line.slice(idx + marker.length).trim().replace(/^[-:]\s*/, '').trim();
338
+ return suffix || undefined;
339
+ }
340
+ function parseEpicChecklistForPrompt(body) {
341
+ const lines = body.split('\n');
342
+ return parseSubIssues(body).map((ref) => ({
343
+ issueNum: ref.number,
344
+ checked: ref.checked,
345
+ title: extractChecklistTitle(lines[ref.lineIndex] ?? '', ref.number),
346
+ }));
347
+ }
348
+ function findMarkdownSection(body, headingPattern) {
349
+ const lines = body.split('\n');
350
+ const section = [];
351
+ let inSection = false;
352
+ for (const line of lines) {
353
+ const heading = /^#{1,6}\s+(.+?)\s*$/.exec(line.trim());
354
+ if (heading) {
355
+ if (inSection)
356
+ break;
357
+ inSection = headingPattern.test(heading[1]);
358
+ continue;
359
+ }
360
+ if (inSection)
361
+ section.push(line);
362
+ }
363
+ return section;
364
+ }
365
+ function removeMarkdownSection(body, headingPattern) {
366
+ const lines = body.split('\n');
367
+ const kept = [];
368
+ let skip = false;
369
+ for (const line of lines) {
370
+ const heading = /^#{1,6}\s+(.+?)\s*$/.exec(line.trim());
371
+ if (heading) {
372
+ if (skip && !headingPattern.test(heading[1])) {
373
+ skip = false;
374
+ }
375
+ else if (headingPattern.test(heading[1])) {
376
+ skip = true;
377
+ continue;
378
+ }
379
+ }
380
+ if (!skip)
381
+ kept.push(line);
382
+ }
383
+ return kept.join('\n');
384
+ }
385
+ function extractEpicAcceptanceCriteria(body) {
386
+ const section = findMarkdownSection(body, /acceptance criteria/i);
387
+ if (section.length === 0)
388
+ return [];
389
+ const listItems = section
390
+ .map((line) => line.trim())
391
+ .filter((line) => /^[-*]\s+/.test(line));
392
+ if (listItems.length > 0)
393
+ return listItems;
394
+ return section
395
+ .map((line) => line.trim())
396
+ .filter(Boolean);
397
+ }
398
+ function summarizeEpicBody(body) {
399
+ const checklistLines = new Set(parseSubIssues(body).map((ref) => ref.lineIndex));
400
+ const withoutChecklist = body
401
+ .split('\n')
402
+ .filter((_, index) => !checklistLines.has(index))
403
+ .join('\n');
404
+ const withoutAcceptance = removeMarkdownSection(withoutChecklist, /acceptance criteria/i);
405
+ const compact = withoutAcceptance
406
+ .replace(/\n{3,}/g, '\n\n')
407
+ .trim();
408
+ if (compact.length <= MAX_EPIC_BODY_SUMMARY_CHARS)
409
+ return compact;
410
+ return `${compact.slice(0, MAX_EPIC_BODY_SUMMARY_CHARS).trimEnd()}\n...(truncated)`;
411
+ }
412
+ function buildEpicPromptContextFromIssue(epic, checklist) {
413
+ return {
414
+ number: epic.number,
415
+ title: epic.title,
416
+ bodySummary: summarizeEpicBody(epic.body),
417
+ acceptanceCriteria: extractEpicAcceptanceCriteria(epic.body),
418
+ subIssues: checklist.map((item) => ({
419
+ issueNum: item.issueNum,
420
+ title: item.title,
421
+ checked: item.checked,
422
+ })),
423
+ };
424
+ }
425
+ function markEpicChecklistItem(checklist, context, issueNum, checked) {
426
+ const item = checklist.find((entry) => entry.issueNum === issueNum);
427
+ if (item)
428
+ item.checked = checked;
429
+ const contextItem = context?.subIssues.find((entry) => entry.issueNum === issueNum);
430
+ if (contextItem)
431
+ contextItem.checked = checked;
432
+ }
242
433
  /**
243
434
  * Run the main loop: poll for issues, process them, finalize session.
244
435
  */
@@ -283,38 +474,13 @@ export async function runCommand(options) {
283
474
  return;
284
475
  }
285
476
  // --- Target selection (epic or milestone) — must happen before session creation ---
286
- let activeEpic;
287
- let activeEpicTitle;
288
- let activeMilestone = config.milestone;
289
- // --epic <N> overrides everything except --verify-only
290
- if (options.epic !== undefined) {
291
- if (typeof options.epic !== 'number' || !Number.isFinite(options.epic) || options.epic <= 0) {
292
- log.error('--epic requires a positive integer issue number (e.g. --epic 165)');
293
- process.exit(1);
294
- }
295
- const epic = getIssueWithComments(config.repo, options.epic);
296
- if (!epic) {
297
- log.error(`Could not fetch epic #${options.epic}`);
298
- process.exit(1);
299
- }
300
- activeEpic = epic.number;
301
- activeEpicTitle = epic.title;
302
- activeMilestone = '';
303
- }
304
- // Interactive picker when TTY and nothing preset
305
- if (activeEpic === undefined && !activeMilestone && !config.dryRun && process.stdin.isTTY) {
306
- const target = await pickTarget(config.repo, {
307
- preferEpics: config.preferEpics,
308
- hideEpics: options.skipEpic === true,
309
- });
310
- if (target.type === 'epic') {
311
- activeEpic = target.epicNum;
312
- activeEpicTitle = target.epicTitle;
313
- }
314
- else if (target.type === 'milestone') {
315
- activeMilestone = target.title;
316
- }
317
- }
477
+ const target = await resolveRunTarget(config, options);
478
+ if (!target)
479
+ return;
480
+ let activeEpic = target.activeEpic;
481
+ let activeEpicTitle = target.activeEpicTitle;
482
+ let activeEpicIssue = target.activeEpicIssue;
483
+ const activeMilestone = target.activeMilestone;
318
484
  if (activeEpic !== undefined) {
319
485
  log.info(`Processing epic #${activeEpic}${activeEpicTitle ? ': ' + activeEpicTitle : ''}`);
320
486
  }
@@ -427,19 +593,31 @@ export async function runCommand(options) {
427
593
  // Otherwise, fetch via the usual project/label/milestone path and exclude
428
594
  // epic-labeled issues (AC #2: epics never picked up by the normal `ready` flow).
429
595
  let issues;
596
+ let epicChecklist = [];
597
+ let epicPromptContext;
430
598
  if (activeEpic !== undefined) {
431
599
  log.info(`Fetching sub-issues of epic #${activeEpic} in checklist order...`);
432
- const refs = getEpicSubIssues(config.repo, activeEpic);
600
+ if (!activeEpicIssue) {
601
+ const epic = getIssueWithComments(config.repo, activeEpic);
602
+ if (!epic) {
603
+ log.error(`Could not fetch epic #${activeEpic}`);
604
+ process.exit(1);
605
+ }
606
+ activeEpicIssue = epic;
607
+ activeEpicTitle = epic.title;
608
+ }
609
+ epicChecklist = parseEpicChecklistForPrompt(activeEpicIssue.body);
433
610
  issues = [];
434
- for (const ref of refs) {
611
+ for (const ref of epicChecklist) {
435
612
  if (ref.checked)
436
613
  continue; // already done
437
- const sub = getIssueWithComments(config.repo, ref.number);
614
+ const sub = getIssueWithComments(config.repo, ref.issueNum);
438
615
  if (!sub) {
439
- log.warn(`Sub-issue #${ref.number} skipped: could not fetch`);
616
+ log.warn(`Sub-issue #${ref.issueNum} skipped: could not fetch`);
440
617
  continue;
441
618
  }
442
- if (sub.labels.includes('epic')) {
619
+ ref.title = ref.title ?? sub.title;
620
+ if (hasEpicLabel(sub)) {
443
621
  log.warn(`Sub-issue #${sub.number} skipped: is itself an epic (nested epics unsupported in v1)`);
444
622
  continue;
445
623
  }
@@ -449,6 +627,7 @@ export async function runCommand(options) {
449
627
  }
450
628
  issues.push(sub);
451
629
  }
630
+ epicPromptContext = buildEpicPromptContextFromIssue(activeEpicIssue, epicChecklist);
452
631
  }
453
632
  else {
454
633
  const milestoneMsg = activeMilestone ? ` in milestone '${activeMilestone}'` : '';
@@ -457,7 +636,7 @@ export async function runCommand(options) {
457
636
  project: config.project,
458
637
  repoOwner: config.repoOwner,
459
638
  milestone: activeMilestone || undefined,
460
- }).filter((iss) => !iss.labels.includes('epic'));
639
+ }).filter((iss) => !hasEpicLabel(iss));
461
640
  }
462
641
  // When set mid-loop, skip post-loop epic verification (e.g. checklist body inconsistency).
463
642
  let epicAbort = false;
@@ -525,7 +704,9 @@ export async function runCommand(options) {
525
704
  log.info('==========================================');
526
705
  activeIssueNum = batchIssues[0].number;
527
706
  try {
528
- const results = await processBatch(batchIssues, config, session);
707
+ const results = epicPromptContext
708
+ ? await processBatch(batchIssues, config, session, { epicContext: epicPromptContext })
709
+ : await processBatch(batchIssues, config, session);
529
710
  session.results.push(...results);
530
711
  // Flip epic checklist for each successful sub-issue.
531
712
  // Skipped in dry-run: `processIssue` returns status='success' when tests are
@@ -537,6 +718,7 @@ export async function runCommand(options) {
537
718
  continue;
538
719
  try {
539
720
  updateEpicChecklist(config.repo, activeEpic, r.issueNum, true);
721
+ markEpicChecklistItem(epicChecklist, epicPromptContext, r.issueNum, true);
540
722
  }
541
723
  catch (err) {
542
724
  log.error(`Epic #${activeEpic} checklist update failed for sub-issue #${r.issueNum}: ${err instanceof Error ? err.message : err}`);
@@ -586,7 +768,9 @@ export async function runCommand(options) {
586
768
  log.info('==========================================');
587
769
  activeIssueNum = issue.number;
588
770
  try {
589
- const result = await processIssue(issue.number, issue.title, issue.body, config, session);
771
+ const result = epicPromptContext
772
+ ? await processIssue(issue.number, issue.title, issue.body, config, session, { epicContext: epicPromptContext })
773
+ : await processIssue(issue.number, issue.title, issue.body, config, session);
590
774
  session.results.push(result);
591
775
  // Flip the epic checklist box when this sub-issue succeeded.
592
776
  // Skipped in dry-run: `processIssue` stubs tests in dry-run and returns success,
@@ -594,6 +778,7 @@ export async function runCommand(options) {
594
778
  if (activeEpic !== undefined && result.status === 'success' && !config.dryRun) {
595
779
  try {
596
780
  updateEpicChecklist(config.repo, activeEpic, issue.number, true);
781
+ markEpicChecklistItem(epicChecklist, epicPromptContext, issue.number, true);
597
782
  }
598
783
  catch (err) {
599
784
  log.error(`Epic #${activeEpic} checklist update failed for sub-issue #${issue.number}: ${err instanceof Error ? err.message : err}`);
@@ -622,7 +807,7 @@ export async function runCommand(options) {
622
807
  // --- Epic completion check: verify and close if all sub-issues are now done ---
623
808
  if (activeEpic !== undefined && !epicAbort && !config.dryRun) {
624
809
  try {
625
- const remaining = getEpicSubIssues(config.repo, activeEpic).filter((r) => !r.checked);
810
+ const remaining = epicChecklist.filter((r) => !r.checked);
626
811
  if (remaining.length === 0) {
627
812
  log.step(`All sub-issues of epic #${activeEpic} are complete — running verification pass`);
628
813
  await runEpicVerificationFlow(activeEpic, config, session);
@@ -695,6 +880,7 @@ export async function runCommand(options) {
695
880
  testsPassing: r.testsPassing,
696
881
  })),
697
882
  includeSecurityScan: !config.skipPostSessionSecurity,
883
+ epicContext: epicPromptContext,
698
884
  visionContext,
699
885
  });
700
886
  // Trace review prompt