@rmartz/pr-lifecycle 8.0.0 → 9.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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runCli
4
- } from "../chunk-ENU2AAWK.js";
4
+ } from "../chunk-4GTGNP35.js";
5
5
 
6
6
  // src/bin/pr-lifecycle.ts
7
7
  process.exitCode = await runCli(
@@ -184,7 +184,8 @@ function parseReconcile(args) {
184
184
  case "--pr":
185
185
  case "--trusted-authors":
186
186
  case "--hold-checks":
187
- case "--ignore-checks": {
187
+ case "--ignore-checks":
188
+ case "--prose-paths": {
188
189
  const value = args[index + 1];
189
190
  if (value === void 0 || value.startsWith("--")) {
190
191
  return usageError(`${arg} requires a value`);
@@ -212,6 +213,7 @@ function parseReconcile(args) {
212
213
  }
213
214
  const holdChecks = listOption(values["--hold-checks"]);
214
215
  const ignoredChecks = listOption(values["--ignore-checks"]);
216
+ const prosePatterns = listOption(values["--prose-paths"]);
215
217
  return {
216
218
  command: "reconcile",
217
219
  owner: repoMatch[1],
@@ -227,7 +229,8 @@ function parseReconcile(args) {
227
229
  },
228
230
  dryRun,
229
231
  json,
230
- tokenAdvisory
232
+ tokenAdvisory,
233
+ ...prosePatterns === void 0 ? {} : { prosePatterns }
231
234
  };
232
235
  }
233
236
  function listOption(value) {
@@ -678,6 +681,7 @@ var LIFECYCLE_LABELS = [
678
681
  "review requested"
679
682
  ];
680
683
  var AUTO_MERGE_LABEL = "auto-merge enabled";
684
+ var DEPENDABOT_REBASING_LABEL = "dependabot rebasing";
681
685
  var UPDATE_REQUIRED_LABEL = "update required";
682
686
  function lifecycleLabels(state) {
683
687
  switch (state) {
@@ -733,8 +737,11 @@ function planReconcile(facts, policy) {
733
737
  autoMerge = facts.immediatelyMergeable ? "merge" : "arm";
734
738
  }
735
739
  }
736
- const owned = [...LIFECYCLE_LABELS];
740
+ const owned = [...LIFECYCLE_LABELS, DEPENDABOT_REBASING_LABEL];
737
741
  const desired = new Set(lifecycleLabels(state));
742
+ if (facts.updater === "dependabot" && facts.dependabotRebasing) {
743
+ desired.add(DEPENDABOT_REBASING_LABEL);
744
+ }
738
745
  if (arming) {
739
746
  owned.push(AUTO_MERGE_LABEL);
740
747
  if (shouldArm && autoMerge !== "merge") {
@@ -763,6 +770,10 @@ function withoutReleaseActions(plan) {
763
770
  // src/github/dependabot-rebase.ts
764
771
  var DEPENDABOT_REBASE_COMMAND = "@dependabot rebase";
765
772
  var DEPENDABOT_REBASING_NOTICE = "Dependabot is rebasing this PR";
773
+ var DEPENDABOT_RECREATING_NOTICE = "Dependabot is recreating this PR";
774
+ function isDependabotRebasing(prBody) {
775
+ return prBody.includes(DEPENDABOT_REBASING_NOTICE) || prBody.includes(DEPENDABOT_RECREATING_NOTICE);
776
+ }
766
777
  function rebaseRequestMarker(headSha) {
767
778
  return `<!-- pr-lifecycle:dependabot-rebase head=${headSha} -->`;
768
779
  }
@@ -772,7 +783,7 @@ function buildRebaseRequestBody(headSha) {
772
783
  ${rebaseRequestMarker(headSha)}`;
773
784
  }
774
785
  function isRebasePending(prBody, comments, headSha) {
775
- if (prBody.includes(DEPENDABOT_REBASING_NOTICE)) {
786
+ if (isDependabotRebasing(prBody)) {
776
787
  return true;
777
788
  }
778
789
  const marker = rebaseRequestMarker(headSha);
@@ -807,6 +818,11 @@ var OWNED_LABEL_DEFINITIONS = {
807
818
  color: "B60205",
808
819
  description: "The PR's required CI (excluding gate checks) is failing on its head."
809
820
  },
821
+ "dependabot rebasing": {
822
+ name: DEPENDABOT_REBASING_LABEL,
823
+ color: "0366D6",
824
+ description: "Dependabot is rebasing or recreating this PR; its branch is about to change."
825
+ },
810
826
  "fix required": {
811
827
  name: "fix required",
812
828
  color: "D93F0B",
@@ -896,6 +912,25 @@ async function updateBranch(release, target) {
896
912
  }
897
913
  }
898
914
 
915
+ // src/lineage/prose.ts
916
+ var DEFAULT_PROSE_PATTERNS = ["*.md", "!index.md"];
917
+ function compile(pattern) {
918
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replaceAll("*", ".*");
919
+ return new RegExp(`^${escaped}$`);
920
+ }
921
+ function proseMatcher(patterns) {
922
+ const include = patterns.filter((pattern) => !pattern.startsWith("!")).map(compile);
923
+ const exclude = patterns.filter((pattern) => pattern.startsWith("!")).map((pattern) => compile(pattern.slice(1)));
924
+ return (path) => {
925
+ const basename2 = path.slice(path.lastIndexOf("/") + 1);
926
+ return include.some((regex) => regex.test(basename2)) && !exclude.some((regex) => regex.test(basename2));
927
+ };
928
+ }
929
+ function overlappingProse(ours, theirs, isProse) {
930
+ const theirSet = new Set(theirs);
931
+ return ours.filter((path) => theirSet.has(path) && isProse(path)).sort();
932
+ }
933
+
899
934
  // src/lineage/git.ts
900
935
  import { execFile } from "child_process";
901
936
  var TIMEOUT_MS = 12e4;
@@ -1007,6 +1042,23 @@ async function createMergeVerifier(git, source) {
1007
1042
  ]);
1008
1043
  return merged.code === 0 && merged.stdout.split("\n")[0]?.trim() === step.tree;
1009
1044
  },
1045
+ async changedPaths(from, to) {
1046
+ if (!OBJECT_ID.test(from) || !OBJECT_ID.test(to)) {
1047
+ return void 0;
1048
+ }
1049
+ const diff = await git.run([
1050
+ "--git-dir",
1051
+ gitDir,
1052
+ "diff-tree",
1053
+ "-r",
1054
+ "-z",
1055
+ "--name-only",
1056
+ "--no-renames",
1057
+ from,
1058
+ to
1059
+ ]);
1060
+ return diff.code === 0 ? diff.stdout.split("\0").filter((path) => path !== "") : void 0;
1061
+ },
1010
1062
  async dispose() {
1011
1063
  await rm(gitDir, { recursive: true, force: true });
1012
1064
  }
@@ -1026,11 +1078,22 @@ async function onBaseBranch(client, commit, baseHeadSha) {
1026
1078
  const { status } = await client.compareCommits(commit, baseHeadSha);
1027
1079
  return status === "identical" || status === "ahead";
1028
1080
  }
1081
+ async function proseOverlapReason(verifier, step, isProse) {
1082
+ const ours = await verifier.changedPaths(step.mergeBase, step.first);
1083
+ const theirs = await verifier.changedPaths(step.mergeBase, step.second);
1084
+ if (ours === void 0 || theirs === void 0) {
1085
+ return "could not list the files each side changed";
1086
+ }
1087
+ const overlap = overlappingProse(ours, theirs, isProse);
1088
+ return overlap.length === 0 ? void 0 : `both sides edited the same prose (${overlap.join(", ")})`;
1089
+ }
1029
1090
  async function walk(client, git, input, wanted) {
1030
1091
  const verifier = await createMergeVerifier(git, input.source);
1031
1092
  if (verifier === void 0) {
1032
1093
  return { cleanAncestors: [], stoppedBecause: "git unavailable or older than 2.40" };
1033
1094
  }
1095
+ const patterns = input.prosePatterns ?? DEFAULT_PROSE_PATTERNS;
1096
+ const isProse = patterns.length === 0 ? void 0 : proseMatcher(patterns);
1034
1097
  const cleanAncestors = [];
1035
1098
  try {
1036
1099
  let current = input.headSha;
@@ -1044,15 +1107,14 @@ async function walk(client, git, input, wanted) {
1044
1107
  return { cleanAncestors, stoppedBecause: `${current} merges a commit not on the base` };
1045
1108
  }
1046
1109
  const { mergeBaseSha } = await client.compareCommits(first, second);
1047
- const clean = await verifier.verify({
1048
- mergeBase: mergeBaseSha,
1049
- first,
1050
- second,
1051
- tree: commit.treeSha
1052
- });
1053
- if (!clean) {
1110
+ const mergeStep = { mergeBase: mergeBaseSha, first, second, tree: commit.treeSha };
1111
+ if (!await verifier.verify(mergeStep)) {
1054
1112
  return { cleanAncestors, stoppedBecause: `${current} is not the clean automatic merge` };
1055
1113
  }
1114
+ const overlap = isProse === void 0 ? void 0 : await proseOverlapReason(verifier, mergeStep, isProse);
1115
+ if (overlap !== void 0) {
1116
+ return { cleanAncestors, stoppedBecause: `${current}: ${overlap}` };
1117
+ }
1056
1118
  cleanAncestors.push(first);
1057
1119
  current = first;
1058
1120
  if ([...wanted].every((sha) => cleanAncestors.includes(sha))) {
@@ -1249,7 +1311,8 @@ async function gatherLineageFor(client, pull, reviews, options) {
1249
1311
  url: pull.cloneUrl,
1250
1312
  ...options.lineage.token === void 0 ? {} : { token: options.lineage.token }
1251
1313
  },
1252
- reviews
1314
+ reviews,
1315
+ ...options.lineage.prosePatterns === void 0 ? {} : { prosePatterns: options.lineage.prosePatterns }
1253
1316
  });
1254
1317
  } catch (error) {
1255
1318
  const message = error instanceof Error ? error.message : String(error);
@@ -1260,7 +1323,7 @@ async function gatherRebasePending(client, pr, pull, updater, policy) {
1260
1323
  if (updater !== "dependabot") {
1261
1324
  return false;
1262
1325
  }
1263
- if (pull.body.includes(DEPENDABOT_REBASING_NOTICE)) {
1326
+ if (isDependabotRebasing(pull.body)) {
1264
1327
  return true;
1265
1328
  }
1266
1329
  const couldUpdate = policy.autoUpdate === true && pull.state === "open" && pull.labels.includes(UPDATE_REQUIRED_LABEL);
@@ -1300,6 +1363,7 @@ async function gatherFacts(client, pr, policy = {}, options = {}) {
1300
1363
  cleanAncestors: lineage?.cleanAncestors ?? [],
1301
1364
  updater,
1302
1365
  rebasePending,
1366
+ dependabotRebasing: updater === "dependabot" && isDependabotRebasing(pull.body),
1303
1367
  reviews: reviews.map((review) => toReviewFact(review, permissions)),
1304
1368
  pendingBotReviewers: pull.requestedBotReviewers
1305
1369
  }
@@ -1409,6 +1473,8 @@ reconcile options:
1409
1473
  --skip-copilot-review Don't wait for requested bot reviewers (deprecated)
1410
1474
  --hold-checks <a,b> Required checks whose pending is a hold (default: pr-policy)
1411
1475
  --ignore-checks <a,b> Required checks CI never counts (default: merge-safety)
1476
+ --prose-paths <a,b> Basename patterns whose overlapping edits in a base merge
1477
+ need a new review (default: *.md,!index.md)
1412
1478
  --dry-run Compute the plan without writing anything
1413
1479
  --json Print one JSON object (schemaVersion 1) on stdout
1414
1480
  --no-token-advisory Don't comment on the PR when arming lacks a release token
@@ -1452,7 +1518,11 @@ async function runCli(argv, io, deps) {
1452
1518
  try {
1453
1519
  const result2 = await reconcilePullRequest(client, args.pr, args.policy, {
1454
1520
  dryRun: args.dryRun,
1455
- lineage: { git: deps.git ?? createGitRunner(), token },
1521
+ lineage: {
1522
+ git: deps.git ?? createGitRunner(),
1523
+ token,
1524
+ ...args.prosePatterns === void 0 ? {} : { prosePatterns: args.prosePatterns }
1525
+ },
1456
1526
  // Only arming, merging, and updating use the release token (never reads).
1457
1527
  // Without one they are skipped, not done with GITHUB_TOKEN; see docs/cli.md.
1458
1528
  release: hasReleaseToken ? clientFor(releaseToken) : "unavailable"
@@ -1519,16 +1589,22 @@ export {
1519
1589
  computeState,
1520
1590
  LIFECYCLE_LABELS,
1521
1591
  AUTO_MERGE_LABEL,
1592
+ DEPENDABOT_REBASING_LABEL,
1522
1593
  UPDATE_REQUIRED_LABEL,
1523
1594
  planReconcile,
1524
1595
  withoutReleaseActions,
1525
1596
  DEPENDABOT_REBASE_COMMAND,
1526
1597
  DEPENDABOT_REBASING_NOTICE,
1598
+ DEPENDABOT_RECREATING_NOTICE,
1599
+ isDependabotRebasing,
1527
1600
  rebaseRequestMarker,
1528
1601
  buildRebaseRequestBody,
1529
1602
  isRebasePending,
1530
1603
  OWNED_LABEL_DEFINITIONS,
1531
1604
  executePlan,
1605
+ DEFAULT_PROSE_PATTERNS,
1606
+ proseMatcher,
1607
+ overlappingProse,
1532
1608
  createGitRunner,
1533
1609
  parseGitVersion,
1534
1610
  createMergeVerifier,
package/dist/index.d.ts CHANGED
@@ -178,6 +178,13 @@ interface PullRequestFacts {
178
178
  * error. Always `false` for other PRs.
179
179
  */
180
180
  rebasePending: boolean;
181
+ /**
182
+ * For a Dependabot PR: the PR body says Dependabot is rebasing or recreating the
183
+ * branch right now. Unlike `rebasePending`, our own request doesn't count — only
184
+ * Dependabot's notice, which it removes when done. Drives the
185
+ * `dependabot rebasing` label. Always `false` for other PRs.
186
+ */
187
+ dependabotRebasing: boolean;
181
188
  reviews: readonly ReviewFact[];
182
189
  /**
183
190
  * Logins of the bots (e.g. Copilot) whose review is requested and not yet
@@ -413,7 +420,7 @@ interface CliDeps {
413
420
  /** Runs git for approval carry-over; tests inject one. Defaults to the real binary. */
414
421
  git?: GitRunner;
415
422
  }
416
- declare const USAGE = "Usage: ai-pr-lifecycle <command> [options]\n\nCommands:\n reconcile Recompute a PR's lifecycle state and converge its labels\n help Show this message\n\nreconcile options:\n --repo <owner/repo> Repository (required)\n --pr <number> Pull request number (required)\n --arm-auto-merge Arm/disarm native auto-merge from the state\n --auto-update Update approved PRs merge-safety flags 'update required'\n (Dependabot PRs are asked to rebase, never updated)\n --trusted-authors <a,b> Only these logins (with write access) may cast verdicts\n --skip-copilot-review Don't wait for requested bot reviewers (deprecated)\n --hold-checks <a,b> Required checks whose pending is a hold (default: pr-policy)\n --ignore-checks <a,b> Required checks CI never counts (default: merge-safety)\n --dry-run Compute the plan without writing anything\n --json Print one JSON object (schemaVersion 1) on stdout\n --no-token-advisory Don't comment on the PR when arming lacks a release token\n\nEnvironment:\n GITHUB_TOKEN Token for reads and writes (required)\n PR_LIFECYCLE_TOKEN\n Real-actor token for arming, merging, and updating;\n without it, labels are kept but those are skipped\n GITHUB_API_URL API base URL (GitHub Enterprise Server)";
423
+ declare const USAGE = "Usage: ai-pr-lifecycle <command> [options]\n\nCommands:\n reconcile Recompute a PR's lifecycle state and converge its labels\n help Show this message\n\nreconcile options:\n --repo <owner/repo> Repository (required)\n --pr <number> Pull request number (required)\n --arm-auto-merge Arm/disarm native auto-merge from the state\n --auto-update Update approved PRs merge-safety flags 'update required'\n (Dependabot PRs are asked to rebase, never updated)\n --trusted-authors <a,b> Only these logins (with write access) may cast verdicts\n --skip-copilot-review Don't wait for requested bot reviewers (deprecated)\n --hold-checks <a,b> Required checks whose pending is a hold (default: pr-policy)\n --ignore-checks <a,b> Required checks CI never counts (default: merge-safety)\n --prose-paths <a,b> Basename patterns whose overlapping edits in a base merge\n need a new review (default: *.md,!index.md)\n --dry-run Compute the plan without writing anything\n --json Print one JSON object (schemaVersion 1) on stdout\n --no-token-advisory Don't comment on the PR when arming lacks a release token\n\nEnvironment:\n GITHUB_TOKEN Token for reads and writes (required)\n PR_LIFECYCLE_TOKEN\n Real-actor token for arming, merging, and updating;\n without it, labels are kept but those are skipped\n GITHUB_API_URL API base URL (GitHub Enterprise Server)";
417
424
  declare function runCli(argv: readonly string[], io: CliIo, deps: CliDeps): Promise<number>;
418
425
 
419
426
  /**
@@ -431,6 +438,8 @@ interface ReconcileArgs {
431
438
  json: boolean;
432
439
  /** Comment on the PR when arming is skipped for want of a release token. */
433
440
  tokenAdvisory: boolean;
441
+ /** Prose basename patterns for carry-over; absent means the default. */
442
+ prosePatterns?: string[];
434
443
  }
435
444
  type ParsedArgs = ReconcileArgs | {
436
445
  command: 'help';
@@ -451,12 +460,18 @@ declare function computeState(facts: PullRequestFacts, policy: ReconcilePolicy):
451
460
  /**
452
461
  * The reconcile plan: the minimal label and auto-merge changes that converge a PR
453
462
  * to its computed lifecycle state. Labels are output only — the core owns the
454
- * lifecycle labels (plus `auto-merge enabled` in arming mode) and never touches
455
- * any other label. See docs/reconciler-design.md §Plan.
463
+ * lifecycle labels and `dependabot rebasing` (plus `auto-merge enabled` in arming
464
+ * mode) and never touches any other label. See docs/reconciler-design.md §Plan.
456
465
  */
457
466
  declare const LIFECYCLE_LABELS: readonly ["approved", "changes requested", "escalation needed", "fix required", "ci failing", "review requested"];
458
467
  type LifecycleLabel = (typeof LIFECYCLE_LABELS)[number];
459
468
  declare const AUTO_MERGE_LABEL = "auto-merge enabled";
469
+ /**
470
+ * Shown while Dependabot rebases or recreates its PR, so workflows can hold off
471
+ * until the branch settles. Owned like the lifecycle labels, but independent of
472
+ * the state.
473
+ */
474
+ declare const DEPENDABOT_REBASING_LABEL = "dependabot rebasing";
460
475
  /** merge-safety's label for a PR whose base moved in a way that matters. Read, never written. */
461
476
  declare const UPDATE_REQUIRED_LABEL = "update required";
462
477
  /**
@@ -502,6 +517,11 @@ interface RepoSource {
502
517
  interface MergeVerifier {
503
518
  /** True only when the step is a verified clean merge; false on any doubt. */
504
519
  verify(step: MergeStep): Promise<boolean>;
520
+ /**
521
+ * Paths that differ between two commits a `verify` call already fetched;
522
+ * undefined on any error, so the caller can fail closed.
523
+ */
524
+ changedPaths(from: string, to: string): Promise<string[] | undefined>;
505
525
  dispose(): Promise<void>;
506
526
  }
507
527
  /**
@@ -515,7 +535,9 @@ declare function createMergeVerifier(git: GitRunner, source: RepoSource): Promis
515
535
  * Finds the head's clean ancestors: commits reached by walking back from the head
516
536
  * through a chain of **verified clean base merges**, so reviews bound to them
517
537
  * still describe the change being merged (docs/reconciler-design.md §Approval
518
- * carry-over). Fails closed: any doubt or error ends the chain, and the cost is
538
+ * carry-over). A clean merge in which both sides edited the same prose file also
539
+ * ends the chain: nothing automatic checks that the merged page still reads
540
+ * correctly. Fails closed: any doubt or error ends the chain, and the cost is
519
541
  * an extra review, never a false approval.
520
542
  */
521
543
  /** A longer chain of base merges than this is unusual enough to review again. */
@@ -527,6 +549,11 @@ interface LineageInput {
527
549
  baseHeadSha: string;
528
550
  source: RepoSource;
529
551
  reviews: readonly ReviewData[];
552
+ /**
553
+ * Basename patterns for prose files (see src/lineage/prose.ts); default
554
+ * `DEFAULT_PROSE_PATTERNS`. Empty turns the prose-overlap check off.
555
+ */
556
+ prosePatterns?: readonly string[];
530
557
  }
531
558
  interface Lineage {
532
559
  cleanAncestors: string[];
@@ -560,6 +587,7 @@ interface GatherOptions {
560
587
  lineage?: {
561
588
  git: GitRunner;
562
589
  token?: string;
590
+ prosePatterns?: readonly string[];
563
591
  };
564
592
  }
565
593
  declare function gatherFacts(client: GitHubClient, pr: number, policy?: ReconcilePolicy, options?: GatherOptions): Promise<GatheredPullRequest>;
@@ -676,6 +704,14 @@ declare function formatSummary(target: ReconcileTarget, result: ReconcileResult)
676
704
  declare const DEPENDABOT_REBASE_COMMAND = "@dependabot rebase";
677
705
  /** Dependabot puts this in the PR body while a rebase runs, and removes it after. */
678
706
  declare const DEPENDABOT_REBASING_NOTICE = "Dependabot is rebasing this PR";
707
+ /** The same notice for `@dependabot recreate`, which force-pushes a fresh branch. */
708
+ declare const DEPENDABOT_RECREATING_NOTICE = "Dependabot is recreating this PR";
709
+ /**
710
+ * Whether Dependabot says, in the PR body, that it is rebasing or recreating the
711
+ * branch right now. Only Dependabot's own notice counts — not our request marker,
712
+ * which means "asked", not "running".
713
+ */
714
+ declare function isDependabotRebasing(prBody: string): boolean;
679
715
  /** Hidden marker recording which head a request was made for. */
680
716
  declare function rebaseRequestMarker(headSha: string): string;
681
717
  /** The command on its own first line, as Dependabot parses it, then the marker. */
@@ -709,7 +745,7 @@ declare function executePlan(client: GitHubClient, target: PlanTarget, plan: Rec
709
745
  * a consumer repo is missing; an existing label's color and description are never
710
746
  * changed.
711
747
  */
712
- declare const OWNED_LABEL_DEFINITIONS: Record<LifecycleLabel | typeof AUTO_MERGE_LABEL, LabelDefinition>;
748
+ declare const OWNED_LABEL_DEFINITIONS: Record<LifecycleLabel | typeof AUTO_MERGE_LABEL | typeof DEPENDABOT_REBASING_LABEL, LabelDefinition>;
713
749
 
714
750
  /**
715
751
  * The advisory comment posted when a PR is ready to arm or merge but no release
@@ -727,6 +763,22 @@ declare function buildTokenAdvisoryBody(skipped: 'arm' | 'merge'): string;
727
763
  */
728
764
  declare function postTokenAdvisory(client: GitHubClient, pr: number, skipped: 'arm' | 'merge'): Promise<boolean>;
729
765
 
766
+ /**
767
+ * Which files are prose for approval carry-over: a clean base merge in which both
768
+ * sides edited the same prose file doesn't carry an approval over, because no CI
769
+ * check can tell whether two concurrent edits to a page still read correctly
770
+ * together (docs/reconciler-design.md §Approval carry-over).
771
+ *
772
+ * Patterns match a file's **basename** with `*` as the only wildcard; a leading
773
+ * `!` excludes. A file is prose when it matches some pattern and no exclusion.
774
+ */
775
+ /** Every Markdown file except index pages, which take routine concurrent appends. */
776
+ declare const DEFAULT_PROSE_PATTERNS: readonly string[];
777
+ type ProseMatcher = (path: string) => boolean;
778
+ declare function proseMatcher(patterns: readonly string[]): ProseMatcher;
779
+ /** Prose paths changed on both sides of a merge, sorted. */
780
+ declare function overlappingProse(ours: readonly string[], theirs: readonly string[], isProse: ProseMatcher): string[];
781
+
730
782
  /**
731
783
  * Verdict parsing and trust. A review is a verdict when it carries a /review
732
784
  * `skill-meta` marker with a verdict outcome, or (with no marker) a native
@@ -747,4 +799,4 @@ declare function isTrustedAuthor(author: ReviewAuthor, policy: ReconcilePolicy):
747
799
  /** The latest verdict that counts for the PR's current head, if any. */
748
800
  declare function currentVerdict(facts: PullRequestFacts, policy: ReconcilePolicy): Verdict | undefined;
749
801
 
750
- export { ACTOR_TYPES, AUTO_MERGE_LABEL, type ActorType, type AutoMergeAction, BRANCH_UPDATERS, type BotEligibility, type BotPrCommit, type BotPrFacts, type BotPrType, type BranchUpdater, type ChangedFile, type CliDeps, type CliIo, type CollaboratorPermission, type CommitData, DEFAULT_SETTLE_MS, DEPENDABOT_LOGIN, DEPENDABOT_REBASE_COMMAND, DEPENDABOT_REBASING_NOTICE, DEPENDABOT_UPDATE_TYPES, type DependabotUpdateType, type GatherOptions, type GatheredPullRequest, GitHubApiError, type GitHubClient, type GitResult, type GitRunner, type HttpClientOptions, LIFECYCLE_LABELS, LIFECYCLE_STATES, type LabelDefinition, type LifecycleLabel, type LifecycleState, type Lineage, type LineageInput, MAX_CHAIN_STEPS, type MergeStep, type MergeVerifier, OWNED_LABEL_DEFINITIONS, PR_STATUSES, type ParsedArgs, type ParsedVerdict, type PlanTarget, type PullRequestData, type PullRequestFacts, type PullRequestStatus, RELEASE_PLEASE_BRANCH_PREFIX, RELEASE_TOKEN_DOCS_URL, REPO_PERMISSIONS, REVIEW_STATES, type ReconcileArgs, type ReconcileJson, type ReconcileOptions, type ReconcilePlan, type ReconcilePolicy, type ReconcileResult, type ReconcileTarget, type ReleaseActions, type ReleaseDiffVerdict, type RepoPermission, type RepoSource, type ReviewAuthor, type ReviewData, type ReviewFact, type ReviewState, SCHEMA_VERSION, type SettleOptions, TOKEN_ADVISORY_MARKER, UPDATE_REQUIRED_LABEL, USAGE, type UpdateAction, VERDICTS, type Verdict, buildRebaseRequestBody, buildTokenAdvisoryBody, classifyBotPr, classifyReleaseDiff, computeState, createGitRunner, createHttpClient, createMergeVerifier, currentVerdict, executePlan, formatSummary, gatherFacts, gatherLineage, isApiStatus, isRebasePending, isTrustedAuthor, isVersionOnlyPatch, parseArgs, parseDependabotUpdateType, parseGitVersion, parseVerdict, planReconcile, postTokenAdvisory, rebaseRequestMarker, reconcilePullRequest, runCli, toReconcileJson, withoutReleaseActions };
802
+ export { ACTOR_TYPES, AUTO_MERGE_LABEL, type ActorType, type AutoMergeAction, BRANCH_UPDATERS, type BotEligibility, type BotPrCommit, type BotPrFacts, type BotPrType, type BranchUpdater, type ChangedFile, type CliDeps, type CliIo, type CollaboratorPermission, type CommitData, DEFAULT_PROSE_PATTERNS, DEFAULT_SETTLE_MS, DEPENDABOT_LOGIN, DEPENDABOT_REBASE_COMMAND, DEPENDABOT_REBASING_LABEL, DEPENDABOT_REBASING_NOTICE, DEPENDABOT_RECREATING_NOTICE, DEPENDABOT_UPDATE_TYPES, type DependabotUpdateType, type GatherOptions, type GatheredPullRequest, GitHubApiError, type GitHubClient, type GitResult, type GitRunner, type HttpClientOptions, LIFECYCLE_LABELS, LIFECYCLE_STATES, type LabelDefinition, type LifecycleLabel, type LifecycleState, type Lineage, type LineageInput, MAX_CHAIN_STEPS, type MergeStep, type MergeVerifier, OWNED_LABEL_DEFINITIONS, PR_STATUSES, type ParsedArgs, type ParsedVerdict, type PlanTarget, type ProseMatcher, type PullRequestData, type PullRequestFacts, type PullRequestStatus, RELEASE_PLEASE_BRANCH_PREFIX, RELEASE_TOKEN_DOCS_URL, REPO_PERMISSIONS, REVIEW_STATES, type ReconcileArgs, type ReconcileJson, type ReconcileOptions, type ReconcilePlan, type ReconcilePolicy, type ReconcileResult, type ReconcileTarget, type ReleaseActions, type ReleaseDiffVerdict, type RepoPermission, type RepoSource, type ReviewAuthor, type ReviewData, type ReviewFact, type ReviewState, SCHEMA_VERSION, type SettleOptions, TOKEN_ADVISORY_MARKER, UPDATE_REQUIRED_LABEL, USAGE, type UpdateAction, VERDICTS, type Verdict, buildRebaseRequestBody, buildTokenAdvisoryBody, classifyBotPr, classifyReleaseDiff, computeState, createGitRunner, createHttpClient, createMergeVerifier, currentVerdict, executePlan, formatSummary, gatherFacts, gatherLineage, isApiStatus, isDependabotRebasing, isRebasePending, isTrustedAuthor, isVersionOnlyPatch, overlappingProse, parseArgs, parseDependabotUpdateType, parseGitVersion, parseVerdict, planReconcile, postTokenAdvisory, proseMatcher, rebaseRequestMarker, reconcilePullRequest, runCli, toReconcileJson, withoutReleaseActions };
package/dist/index.js CHANGED
@@ -2,10 +2,13 @@ import {
2
2
  ACTOR_TYPES,
3
3
  AUTO_MERGE_LABEL,
4
4
  BRANCH_UPDATERS,
5
+ DEFAULT_PROSE_PATTERNS,
5
6
  DEFAULT_SETTLE_MS,
6
7
  DEPENDABOT_LOGIN,
7
8
  DEPENDABOT_REBASE_COMMAND,
9
+ DEPENDABOT_REBASING_LABEL,
8
10
  DEPENDABOT_REBASING_NOTICE,
11
+ DEPENDABOT_RECREATING_NOTICE,
9
12
  DEPENDABOT_UPDATE_TYPES,
10
13
  GitHubApiError,
11
14
  LIFECYCLE_LABELS,
@@ -36,29 +39,35 @@ import {
36
39
  gatherFacts,
37
40
  gatherLineage,
38
41
  isApiStatus,
42
+ isDependabotRebasing,
39
43
  isRebasePending,
40
44
  isTrustedAuthor,
41
45
  isVersionOnlyPatch,
46
+ overlappingProse,
42
47
  parseArgs,
43
48
  parseDependabotUpdateType,
44
49
  parseGitVersion,
45
50
  parseVerdict,
46
51
  planReconcile,
47
52
  postTokenAdvisory,
53
+ proseMatcher,
48
54
  rebaseRequestMarker,
49
55
  reconcilePullRequest,
50
56
  runCli,
51
57
  toReconcileJson,
52
58
  withoutReleaseActions
53
- } from "./chunk-ENU2AAWK.js";
59
+ } from "./chunk-4GTGNP35.js";
54
60
  export {
55
61
  ACTOR_TYPES,
56
62
  AUTO_MERGE_LABEL,
57
63
  BRANCH_UPDATERS,
64
+ DEFAULT_PROSE_PATTERNS,
58
65
  DEFAULT_SETTLE_MS,
59
66
  DEPENDABOT_LOGIN,
60
67
  DEPENDABOT_REBASE_COMMAND,
68
+ DEPENDABOT_REBASING_LABEL,
61
69
  DEPENDABOT_REBASING_NOTICE,
70
+ DEPENDABOT_RECREATING_NOTICE,
62
71
  DEPENDABOT_UPDATE_TYPES,
63
72
  GitHubApiError,
64
73
  LIFECYCLE_LABELS,
@@ -89,15 +98,18 @@ export {
89
98
  gatherFacts,
90
99
  gatherLineage,
91
100
  isApiStatus,
101
+ isDependabotRebasing,
92
102
  isRebasePending,
93
103
  isTrustedAuthor,
94
104
  isVersionOnlyPatch,
105
+ overlappingProse,
95
106
  parseArgs,
96
107
  parseDependabotUpdateType,
97
108
  parseGitVersion,
98
109
  parseVerdict,
99
110
  planReconcile,
100
111
  postTokenAdvisory,
112
+ proseMatcher,
101
113
  rebaseRequestMarker,
102
114
  reconcilePullRequest,
103
115
  runCli,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmartz/pr-lifecycle",
3
- "version": "8.0.0",
3
+ "version": "9.1.0",
4
4
  "description": "Event-driven PR lifecycle reconciler: recomputes a pull request's lifecycle labels from its current facts on every GitHub event and arms native auto-merge on approval.",
5
5
  "keywords": [
6
6
  "ci",