@joshuafolkken/kit 1.1166.0 → 1.1178.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 (61) hide show
  1. package/.claude/skills/workflow-commands/backlogrun-lanes.md +3 -3
  2. package/.claude/skills/workflow-commands/backlogrun-park.md +6 -7
  3. package/.claude/skills/workflow-commands/backlogrun-steps.md +3 -2
  4. package/.claude/skills/workflow-commands/pre-gate-cut.md +4 -4
  5. package/.github/workflows/ci.yml +15 -2
  6. package/dist/hooks/batch-guard.js +4 -4
  7. package/dist/hooks/{chunk-5KTCMCOT.js → chunk-32GQTL4F.js} +1 -1
  8. package/dist/hooks/{chunk-URJA6XY4.js → chunk-DO6NWWHU.js} +4 -4
  9. package/dist/hooks/{chunk-GU5MATVE.js → chunk-G6KRCKEC.js} +11 -19
  10. package/dist/hooks/{chunk-ZDZ555YH.js → chunk-GDS5N2KB.js} +88 -291
  11. package/dist/hooks/{chunk-GYNGP7HI.js → chunk-I4XSL4TT.js} +1 -1
  12. package/dist/hooks/{chunk-DYAVAM6S.js → chunk-S6X6WYKR.js} +324 -49
  13. package/dist/hooks/{chunk-ANJ2WGFD.js → chunk-UAGLLIGZ.js} +1 -1
  14. package/dist/hooks/{chunk-ENA7P5FB.js → chunk-VESKRQOF.js} +3 -3
  15. package/dist/hooks/{chunk-V2BTOZHT.js → chunk-VQLLNFNT.js} +3 -3
  16. package/dist/hooks/{chunk-A6P7PN7P.js → chunk-ZAL3NRGL.js} +2 -2
  17. package/dist/hooks/codex-hook-adapter.js +10 -10
  18. package/dist/hooks/duplicate-read-guard.js +5 -5
  19. package/dist/hooks/format-edited.js +2 -2
  20. package/dist/hooks/inputs.json +192 -192
  21. package/dist/hooks/investigation-guard.js +5 -5
  22. package/dist/hooks/pretool-guard.js +9 -9
  23. package/dist/hooks/stop-guard.js +18 -4
  24. package/dist/josh.js +4 -1
  25. package/package.json +1 -1
  26. package/scripts/backlog/backlog-next.ts +15 -4
  27. package/scripts/backlog/backlog-plan-cli.ts +6 -5
  28. package/scripts/backlog/backlog-rank.ts +18 -9
  29. package/scripts/backlog/backlog-restructure.ts +152 -0
  30. package/scripts/backlog/backlog-waves.ts +15 -17
  31. package/scripts/cost-runtime/context-cut-threshold.ts +1 -9
  32. package/scripts/cost-runtime/cost-verdict.ts +15 -28
  33. package/scripts/followup/git-followup-stages.ts +9 -0
  34. package/scripts/followup/git-pr-followup.ts +1 -1
  35. package/scripts/gh/git-gh-issue.ts +5 -3
  36. package/scripts/gh/git-gh-pr-read.ts +4 -0
  37. package/scripts/gh/git-pr-checks-eval.ts +8 -0
  38. package/scripts/gh/git-pr-checks.ts +11 -1
  39. package/scripts/git/constants.ts +10 -0
  40. package/scripts/git/main-merge.ts +57 -21
  41. package/scripts/git/schemas.ts +2 -0
  42. package/scripts/josh/josh-commands-development.ts +1 -1
  43. package/scripts/lane/lane-launch-cli.ts +21 -3
  44. package/scripts/notify/telegram-notify.ts +26 -1
  45. package/scripts/rules/pre-gate-cut.ts +2 -2
  46. package/scripts/run/run-carry.ts +11 -5
  47. package/scripts/run/run-cut-cli.ts +1 -1
  48. package/scripts/run/run-cut-report.ts +2 -2
  49. package/scripts/run/run-ship-cli.ts +27 -6
  50. package/scripts/run/run-ship-next.ts +13 -0
  51. package/scripts/run/run-ship-pre-detach.ts +66 -0
  52. package/scripts/run/run-ship-return.ts +7 -4
  53. package/scripts/run/run-ship-stage.ts +13 -0
  54. package/scripts/run/run-ship-steps.ts +10 -2
  55. package/scripts/run/run-ship-sync.ts +114 -0
  56. package/scripts/run/run-ship.ts +6 -0
  57. package/scripts/run/run-wake-cli.ts +8 -1
  58. package/scripts/run/run-wake-driver.ts +42 -11
  59. package/scripts/test/test-red-logic.ts +17 -2
  60. package/scripts/test/test-red.ts +8 -7
  61. package/scripts/time-runtime/time-transcript-line.ts +27 -1
@@ -1,20 +1,33 @@
1
1
  import {
2
2
  lane_child_marker,
3
3
  run_issue_number
4
- } from "./chunk-5KTCMCOT.js";
4
+ } from "./chunk-32GQTL4F.js";
5
5
  import {
6
+ CHECK_STATUS_FAIL,
7
+ CHECK_STATUS_PENDING,
6
8
  PLATFORM_TEMP_ROOT,
9
+ PrConflictError,
10
+ blocking_issue_schema,
7
11
  cost_blocks,
8
12
  cost_transcript,
9
13
  cost_usage,
14
+ describe_pr_failure,
15
+ evaluate_pr_state,
10
16
  file_reader,
17
+ is_coderabbit_check,
18
+ is_merge_conflict,
19
+ is_required_check,
20
+ is_review_decision_decisive,
11
21
  json_value,
12
22
  lane_paths,
23
+ parse_pr_state_snapshot,
24
+ read_string,
25
+ rest_comment_schema,
13
26
  stamp_file,
14
27
  time_density_hook,
15
28
  time_shell,
16
29
  time_transcript_line
17
- } from "./chunk-DYAVAM6S.js";
30
+ } from "./chunk-S6X6WYKR.js";
18
31
  import {
19
32
  ENV_FILE_NAME,
20
33
  LANE_SEAT_KEY,
@@ -168,6 +181,7 @@ import { platform } from "node:os";
168
181
  var GIT_COMMAND_UNIX = "/usr/bin/git";
169
182
  var PORCELAIN_FLAG = "--porcelain";
170
183
  var UNTRACKED_FILES_FLAG = "--untracked-files=all";
184
+ var GIT_BINARY_KEY = "JOSH_GIT_BINARY";
171
185
  function get_git_command() {
172
186
  if (platform() === "win32") {
173
187
  return String.raw`"C:\Program Files\Git\cmd\git.exe"`;
@@ -175,6 +189,8 @@ function get_git_command() {
175
189
  return GIT_COMMAND_UNIX;
176
190
  }
177
191
  function get_git_command_for_spawn() {
192
+ const binary = process.env[GIT_BINARY_KEY];
193
+ if (binary !== void 0 && binary !== "") return binary;
178
194
  if (platform() === "win32") {
179
195
  return String.raw`C:\Program Files\Git\cmd\git.exe`;
180
196
  }
@@ -1319,7 +1335,6 @@ var context_cut_payback = {
1319
1335
 
1320
1336
  // scripts/cost-runtime/context-cut-threshold.ts
1321
1337
  var CONTEXT_CUT_THRESHOLD = context_cut_payback.break_even_context();
1322
- var RECENT_REQUEST_WINDOW = 10;
1323
1338
 
1324
1339
  // scripts/git/git-common-directory.ts
1325
1340
  import { execFileSync } from "node:child_process";
@@ -1415,6 +1430,7 @@ var STAGE = {
1415
1430
  PREFLIGHT: "preflight",
1416
1431
  REVIEW: "review",
1417
1432
  GATE: "gate",
1433
+ SYNC: "sync",
1418
1434
  COMMIT: "commit",
1419
1435
  ROUND_TWO: "round-2",
1420
1436
  FOLLOWUP: "followup",
@@ -1464,6 +1480,9 @@ var DONE_BY = {
1464
1480
  // the recorded round, and only a commit pins the tree that round read.
1465
1481
  [STAGE.REVIEW]: (_done, state) => state.is_merged || state.is_committed,
1466
1482
  [STAGE.GATE]: (_done, state) => state.is_merged || state.is_committed,
1483
+ // The merge of the default branch before the commit (joshuafolkken/kit#3221): once committed, a
1484
+ // conflicting pull request is the followup's to merge again.
1485
+ [STAGE.SYNC]: (_done, state) => state.is_merged || state.is_committed,
1467
1486
  [STAGE.COMMIT]: (done, state) => state.is_merged || done.has(STAGE.COMMIT) && is_shipped(state),
1468
1487
  // The round-2 pass (joshuafolkken/kit#2489) reads the pushed fix delta, so its record is honored only
1469
1488
  // while that push still stands — new work pushed on top reruns it.
@@ -1484,6 +1503,10 @@ function commit_flags(state) {
1484
1503
  function event_text(issue, stage, phase) {
1485
1504
  return `#${issue} ${stage} ${phase}`;
1486
1505
  }
1506
+ var CONFLICT = "conflict";
1507
+ function stop_reason2(stage, conflicts = []) {
1508
+ return conflicts.length > 0 ? CONFLICT : stage;
1509
+ }
1487
1510
  var run_ship_stage = {
1488
1511
  PHASE,
1489
1512
  STAGE,
@@ -1493,7 +1516,8 @@ var run_ship_stage = {
1493
1516
  is_done,
1494
1517
  mark_done,
1495
1518
  read_done,
1496
- record_path
1519
+ record_path,
1520
+ stop_reason: stop_reason2
1497
1521
  };
1498
1522
 
1499
1523
  // scripts/run/run-ship-next.ts
@@ -1534,12 +1558,18 @@ var AFTER_FIX = {
1534
1558
  [STAGE2.PREFLIGHT]: detach_as_started,
1535
1559
  [STAGE2.REVIEW]: detach_as_started,
1536
1560
  [STAGE2.GATE]: detach_as_started,
1561
+ [STAGE2.SYNC]: detach_as_started,
1537
1562
  [STAGE2.COMMIT]: detach_as_started,
1538
1563
  [STAGE2.ROUND_TWO]: detach_again,
1539
1564
  [STAGE2.FOLLOWUP]: detach_again,
1540
1565
  [STAGE2.REPORT]: detach_again
1541
1566
  };
1567
+ function conflict_step(conflicts) {
1568
+ return `Resolve the conflict with origin/main in ${conflicts.join(", ")} (the merge is left in progress: remove the conflict markers in those files), then`;
1569
+ }
1542
1570
  function next_step(issue, stage, resume) {
1571
+ const conflicts = resume.conflicts ?? [];
1572
+ if (conflicts.length > 0) return `${conflict_step(conflicts)} ${AFTER_FIX[stage](resume)}`;
1543
1573
  return `Read the stopped report with \`${COMMAND.LOG} ${issue}\`, fix the ${stage} failure, then ${AFTER_FIX[stage](resume)}`;
1544
1574
  }
1545
1575
  var run_ship_next = { COMMAND, next_step, quoted, resume_of };
@@ -2758,8 +2788,11 @@ function mismatch_message(carry, invocation) {
2758
2788
  function busy_message2(carry) {
2759
2789
  return `A live run holds this budget \u2014 ${describe_carry(carry)}, owner pid ${String(carry.owner_pid)} still running. Nothing was established. Wait for that run, or end its record with \`${END_COMMAND2}\` once you know it is over.`;
2760
2790
  }
2791
+ function claim_command(invocation) {
2792
+ return `${RESUME_COMMAND} "${invocation}" ${OWNER_ARGUMENT}`;
2793
+ }
2761
2794
  function standing_message(carry) {
2762
- return `A run record is standing here that no cut handed off \u2014 ${describe_carry(carry)}. Nothing was established. Carry that budget with \`${RESUME_COMMAND} "${carry.invocation}" ${OWNER_ARGUMENT}\`, or discard it with \`${END_COMMAND2}\` and begin again.`;
2795
+ return `A run record is standing here that no cut handed off \u2014 ${describe_carry(carry)}. Nothing was established. Carry that budget with \`${claim_command(carry.invocation)}\`, or discard it with \`${END_COMMAND2}\` and begin again.`;
2763
2796
  }
2764
2797
  function count_refused_message(carry) {
2765
2798
  if (carry.is_handed_off === true) {
@@ -2791,6 +2824,7 @@ var run_carry = {
2791
2824
  begin_carry,
2792
2825
  busy_message: busy_message2,
2793
2826
  carry_path,
2827
+ claim_command,
2794
2828
  classify: classify3,
2795
2829
  classify_claim,
2796
2830
  count_refused_message,
@@ -4851,77 +4885,8 @@ var git_gh_helpers = {
4851
4885
  handle_pr_create_error
4852
4886
  };
4853
4887
 
4854
- // scripts/git/schemas.ts
4855
- import { z as z11 } from "zod";
4856
- var package_name_schema = z11.object({ name: z11.string().min(1) });
4857
- var rollup_item_schema = z11.looseObject({
4858
- // eslint-disable-next-line @typescript-eslint/naming-convention -- GraphQL field name from GitHub API
4859
- __typename: z11.string().optional(),
4860
- state: z11.string().optional(),
4861
- status: z11.string().optional(),
4862
- conclusion: z11.string().optional(),
4863
- name: z11.string().optional(),
4864
- context: z11.string().optional()
4865
- });
4866
- var pr_raw_schema = z11.object({
4867
- statusCheckRollup: z11.array(rollup_item_schema).optional(),
4868
- mergeStateStatus: z11.string().optional(),
4869
- reviewDecision: z11.string().optional()
4870
- });
4871
- var pull_comment_schema = z11.object({
4872
- body: z11.string().optional(),
4873
- html_url: z11.string().optional(),
4874
- user: z11.object({ login: z11.string().optional() }).optional()
4875
- });
4876
- var ai_review_pull_comment_schema = z11.object({
4877
- body: z11.string().optional(),
4878
- url: z11.string().optional(),
4879
- author: z11.object({ login: z11.string().optional() }).optional()
4880
- });
4881
- var pr_info_schema = z11.object({
4882
- mergeable: z11.union([z11.boolean(), z11.string()]).nullable().optional(),
4883
- mergeStateStatus: z11.string().nullable().optional(),
4884
- state: z11.string().optional()
4885
- });
4886
- var epic_issue_schema = z11.object({
4887
- number: z11.number(),
4888
- body: z11.string().optional()
4889
- });
4890
- var blocking_issue_schema = z11.object({
4891
- number: z11.number(),
4892
- state: z11.string().optional(),
4893
- repository_url: z11.string().optional()
4894
- });
4895
- var blocked_by_schema = z11.object({
4896
- nodes: z11.array(blocking_issue_schema).default([]),
4897
- totalCount: z11.number().optional()
4898
- }).optional();
4899
- var epic_child_schema = z11.object({
4900
- state: z11.string().optional(),
4901
- blockedBy: blocked_by_schema
4902
- });
4903
- var rest_comment_schema = z11.looseObject({
4904
- body: z11.string().nullish(),
4905
- html_url: z11.string().optional(),
4906
- user: z11.looseObject({ login: z11.string().optional() }).nullish()
4907
- });
4908
- var issue_label_schema = z11.object({ name: z11.string() });
4909
- var epic_subject_schema = z11.object({
4910
- number: z11.number(),
4911
- state: z11.string().optional(),
4912
- labels: z11.array(issue_label_schema).optional(),
4913
- body: z11.string().optional()
4914
- });
4915
- var open_issue_schema = z11.object({
4916
- number: z11.number(),
4917
- title: z11.string(),
4918
- labels: z11.array(issue_label_schema).optional(),
4919
- createdAt: z11.string(),
4920
- blockedBy: blocked_by_schema
4921
- });
4922
-
4923
4888
  // scripts/gh/git-gh-issue-rest.ts
4924
- import { z as z12 } from "zod";
4889
+ import { z as z11 } from "zod";
4925
4890
 
4926
4891
  // scripts/gh/git-gh-rest-state.ts
4927
4892
  var MERGED_STATE = "MERGED";
@@ -4930,11 +4895,11 @@ function to_gh_state(state) {
4930
4895
  }
4931
4896
 
4932
4897
  // scripts/gh/git-gh-issue-rest.ts
4933
- var rest_issue_schema = z12.looseObject({
4934
- number: z12.number(),
4935
- issue_dependencies_summary: z12.looseObject({ total_blocked_by: z12.number().optional() }).nullish(),
4898
+ var rest_issue_schema = z11.looseObject({
4899
+ number: z11.number(),
4900
+ issue_dependencies_summary: z11.looseObject({ total_blocked_by: z11.number().optional() }).nullish(),
4936
4901
  // Present only on a pull request, which this endpoint serves as readily as an issue.
4937
- pull_request: z12.looseObject({ merged_at: z12.string().nullish() }).nullish()
4902
+ pull_request: z11.looseObject({ merged_at: z11.string().nullish() }).nullish()
4938
4903
  });
4939
4904
  var REPOSITORY_URL = /\/repos\/([\w.-]+\/[\w.-]+)$/u;
4940
4905
  var REPOSITORY_URL_GROUP = 1;
@@ -5419,7 +5384,7 @@ var NUMBER_AND_BODY_FIELDS = "number,body";
5419
5384
  var BACKLOG_SCAN_FIELDS = `number,title,body,${BLOCKED_BY_COUNT_FIELD}`;
5420
5385
  var NUMBER_TITLE_AND_LABELS_FIELDS = "number,title,labels";
5421
5386
  var SUMMARY_FIELDS = "number,title,labels,createdAt";
5422
- var PICKUP_FIELDS = `${SUMMARY_FIELDS},blockedBy`;
5387
+ var PICKUP_FIELDS = `${SUMMARY_FIELDS},blockedBy,body`;
5423
5388
  var { issue_list: issue_list2 } = git_gh_issue_list;
5424
5389
  async function issue_list_recent(limit) {
5425
5390
  return await issue_list2({ json_fields: SUMMARY_FIELDS, limit });
@@ -5470,18 +5435,18 @@ var git_gh_issue = {
5470
5435
  // scripts/ci/pr-classification.ts
5471
5436
  import { readFileSync as readFileSync4 } from "node:fs";
5472
5437
  import { fileURLToPath as fileURLToPath2 } from "node:url";
5473
- import { z as z13 } from "zod";
5438
+ import { z as z12 } from "zod";
5474
5439
  var CLASSIFICATION_SET = new Set(RELEASE_CLASSIFICATION_NAMES);
5475
5440
  var ISSUE_BUG_LABEL = "bug";
5476
5441
  var DECLARATION_PREFIX = "- \u30EA\u30EA\u30FC\u30B9\u5206\u985E: ";
5477
5442
  var DECLARATION = new RegExp(`^${DECLARATION_PREFIX}(.+)$`, "gmu");
5478
5443
  var LEGACY_LABELS = /* @__PURE__ */ new Set(["semver-major", "semver-minor"]);
5479
- var LABEL = z13.object({ name: z13.string() });
5480
- var USER = z13.object({ login: z13.string() });
5481
- var PULL_REQUEST = z13.object({ number: z13.number(), user: USER });
5482
- var EVENT = z13.object({
5444
+ var LABEL = z12.object({ name: z12.string() });
5445
+ var USER = z12.object({ login: z12.string() });
5446
+ var PULL_REQUEST = z12.object({ number: z12.number(), user: USER });
5447
+ var EVENT = z12.object({
5483
5448
  pull_request: PULL_REQUEST,
5484
- repository: z13.object({ full_name: z13.string() })
5449
+ repository: z12.object({ full_name: z12.string() })
5485
5450
  });
5486
5451
  function classification_error(labels, author) {
5487
5452
  const legacy = labels.filter((label2) => LEGACY_LABELS.has(label2.toLowerCase()));
@@ -5504,7 +5469,7 @@ function release_candidates(candidates) {
5504
5469
  return candidates.filter((candidate) => candidate !== ENHANCEMENT_LABEL);
5505
5470
  }
5506
5471
  function issue_candidates(issue_json) {
5507
- const issue = z13.object({ labels: z13.array(LABEL), body: z13.string().nullable() }).parse(JSON.parse(issue_json));
5472
+ const issue = z12.object({ labels: z12.array(LABEL), body: z12.string().nullable() }).parse(JSON.parse(issue_json));
5508
5473
  const names = issue.labels.map((label2) => label2.name.toLowerCase());
5509
5474
  const declared = [...(issue.body ?? "").matchAll(DECLARATION)].map((match) => match[1] ?? "");
5510
5475
  const candidates = [...release_candidates([...names, ...declared].filter(is_classification))];
@@ -5579,31 +5544,31 @@ async function poll_until(is_done2, options) {
5579
5544
  var poll = { poll_until, sleep: sleep3 };
5580
5545
 
5581
5546
  // scripts/gh/git-gh-pr.ts
5582
- import { z as z17 } from "zod";
5547
+ import { z as z16 } from "zod";
5583
5548
 
5584
5549
  // scripts/gh/git-gh-pr-rest.ts
5585
- import { z as z14 } from "zod";
5586
- var rest_repo_schema = z14.looseObject({ full_name: z14.string().optional() }).nullish();
5587
- var rest_pull_side_schema = z14.looseObject({ repo: rest_repo_schema });
5588
- var rest_pull_schema = z14.looseObject({
5589
- number: z14.number(),
5590
- html_url: z14.string().optional(),
5591
- body: z14.string().nullish(),
5592
- state: z14.string().optional(),
5593
- merged: z14.boolean().nullish(),
5594
- merged_at: z14.string().nullish(),
5595
- mergeable: z14.boolean().nullish(),
5596
- mergeable_state: z14.string().optional(),
5550
+ import { z as z13 } from "zod";
5551
+ var rest_repo_schema = z13.looseObject({ full_name: z13.string().optional() }).nullish();
5552
+ var rest_pull_side_schema = z13.looseObject({ repo: rest_repo_schema });
5553
+ var rest_pull_schema = z13.looseObject({
5554
+ number: z13.number(),
5555
+ html_url: z13.string().optional(),
5556
+ body: z13.string().nullish(),
5557
+ state: z13.string().optional(),
5558
+ merged: z13.boolean().nullish(),
5559
+ merged_at: z13.string().nullish(),
5560
+ mergeable: z13.boolean().nullish(),
5561
+ mergeable_state: z13.string().optional(),
5597
5562
  // `sha` is the head commit, which is what both halves of the merge-gate rollup are keyed by —
5598
5563
  // REST hangs the check runs and the status contexts off the commit rather than off the pull
5599
5564
  // request (joshuafolkken/kit#1028).
5600
- head: z14.looseObject({ ref: z14.string().optional(), sha: z14.string().optional(), repo: rest_repo_schema }).nullish(),
5565
+ head: z13.looseObject({ ref: z13.string().optional(), sha: z13.string().optional(), repo: rest_repo_schema }).nullish(),
5601
5566
  base: rest_pull_side_schema.nullish(),
5602
5567
  // `node_id` is what the GraphQL auto-merge mutation addresses a pull request by, and `auto_merge`
5603
5568
  // is `null` until auto-merge is enabled — both read by `git-gh-pr-auto-merge.ts`
5604
5569
  // (joshuafolkken/kit#2497).
5605
- node_id: z14.string().optional(),
5606
- auto_merge: z14.looseObject({}).nullish()
5570
+ node_id: z13.string().optional(),
5571
+ auto_merge: z13.looseObject({}).nullish()
5607
5572
  });
5608
5573
  var NOT_A_PULL_MESSAGE = "gh api answered something other than a pull request object";
5609
5574
  var NOT_A_PULL_LISTING_MESSAGE = "gh api answered something other than a pull request listing";
@@ -5756,7 +5721,8 @@ async function pr_get_merge_state(branch_name) {
5756
5721
  return {
5757
5722
  is_merged: git_gh_pr_rest.is_merged(pull),
5758
5723
  merged_at: pull.merged_at ?? void 0,
5759
- head_sha: pull.head?.sha
5724
+ head_sha: pull.head?.sha,
5725
+ merge_state_status: to_gh_state(pull.mergeable_state)
5760
5726
  };
5761
5727
  }
5762
5728
  async function pr_get_body(branch_name) {
@@ -5803,14 +5769,14 @@ var git_gh_pr_read = {
5803
5769
  };
5804
5770
 
5805
5771
  // scripts/gh/git-gh-pr-review.ts
5806
- import { z as z15 } from "zod";
5772
+ import { z as z14 } from "zod";
5807
5773
  var REVIEW_APPROVED = "APPROVED";
5808
5774
  var REVIEW_CHANGES_REQUESTED = "CHANGES_REQUESTED";
5809
5775
  var REVIEW_NONE = "";
5810
5776
  var STATE_CHANGING_REVIEWS = /* @__PURE__ */ new Set([REVIEW_APPROVED, REVIEW_CHANGES_REQUESTED]);
5811
- var rest_review_schema = z15.looseObject({
5812
- state: z15.string().optional(),
5813
- user: z15.looseObject({ login: z15.string().optional() }).nullish()
5777
+ var rest_review_schema = z14.looseObject({
5778
+ state: z14.string().optional(),
5779
+ user: z14.looseObject({ login: z14.string().optional() }).nullish()
5814
5780
  });
5815
5781
  var NOT_A_REVIEW_LISTING = "gh api answered something other than a review listing";
5816
5782
  function parse_rest_reviews(reviews_json) {
@@ -5843,18 +5809,18 @@ function to_review_decision(reviews_json) {
5843
5809
  var git_gh_pr_review = { to_review_decision };
5844
5810
 
5845
5811
  // scripts/gh/git-gh-pr-rollup.ts
5846
- import { z as z16 } from "zod";
5812
+ import { z as z15 } from "zod";
5847
5813
  var STATUS_CONTEXT_TYPE_NAME = "StatusContext";
5848
5814
  var TYPE_NAME_KEY = "__typename";
5849
- var rollup_element_schema = z16.looseObject({});
5850
- var check_runs_page_schema = z16.looseObject({
5815
+ var rollup_element_schema = z15.looseObject({});
5816
+ var check_runs_page_schema = z15.looseObject({
5851
5817
  // Required, not optional: GitHub always names the key, and accepting a page without one would
5852
5818
  // answer an empty rollup — which `git-pr-followup.ts` reports as "this branch has no checks".
5853
- check_runs: z16.array(rollup_element_schema)
5819
+ check_runs: z15.array(rollup_element_schema)
5854
5820
  });
5855
- var id_holder_schema = z16.object({ id: z16.number() });
5856
- var status_page_schema = z16.looseObject({
5857
- statuses: z16.array(rollup_element_schema)
5821
+ var id_holder_schema = z15.object({ id: z15.number() });
5822
+ var status_page_schema = z15.looseObject({
5823
+ statuses: z15.array(rollup_element_schema)
5858
5824
  });
5859
5825
  var NOT_A_CHECK_RUNS_LISTING = "gh api answered something other than a check run listing";
5860
5826
  var NOT_A_STATUS_LISTING = "gh api answered something other than a commit status listing";
@@ -5988,7 +5954,7 @@ var MERGE_READ_BACK_ATTEMPTS = 3;
5988
5954
  var MERGE_READ_BACK_INTERVAL_MS = 1e3;
5989
5955
  var PR_NUMBER_PATTERN = /\/pull\/([1-9]\d*)$/u;
5990
5956
  var LABELS_SEGMENT2 = "/labels";
5991
- var PR_LABELS = z17.array(z17.object({ name: z17.string() }));
5957
+ var PR_LABELS = z16.array(z16.object({ name: z16.string() }));
5992
5958
  async function add_pr_classification(number, label2) {
5993
5959
  await git_gh_exec.exec_gh_api({
5994
5960
  path: `${git_gh_api_path.issue_api_path(number)}${LABELS_SEGMENT2}`,
@@ -6156,178 +6122,6 @@ var git_gh_repo = {
6156
6122
  repo_get_name_with_owner
6157
6123
  };
6158
6124
 
6159
- // scripts/gh/git-pr-checks-parse.ts
6160
- var CHECK_STATUS_PASS = "pass";
6161
- var CHECK_STATUS_PENDING = "pending";
6162
- var CHECK_STATUS_FAIL = "fail";
6163
- var CHECK_STATUS_MISSING = "missing";
6164
- var PASSING_CONCLUSIONS = /* @__PURE__ */ new Set(["success", "skipped", "neutral"]);
6165
- var KEY_TYPE_NAME = "__typename";
6166
- var KEY_STATE = "state";
6167
- var KEY_STATUS = "status";
6168
- var KEY_CONCLUSION = "conclusion";
6169
- var KEY_NAME = "name";
6170
- var KEY_CONTEXT = "context";
6171
- function read_string(value) {
6172
- if (typeof value !== "string") return void 0;
6173
- const trimmed2 = value.trim();
6174
- if (trimmed2.length === 0) return void 0;
6175
- return trimmed2;
6176
- }
6177
- var PENDING_STATUS_STATES = /* @__PURE__ */ new Set(["pending", "expected"]);
6178
- function parse_status_context(item) {
6179
- const state = read_string(item[KEY_STATE])?.toLowerCase();
6180
- if (state === "success") return CHECK_STATUS_PASS;
6181
- if (state !== void 0 && PENDING_STATUS_STATES.has(state)) return CHECK_STATUS_PENDING;
6182
- return CHECK_STATUS_FAIL;
6183
- }
6184
- function is_passing_conclusion(item) {
6185
- const conclusion = read_string(item[KEY_CONCLUSION])?.toLowerCase();
6186
- return conclusion !== void 0 && PASSING_CONCLUSIONS.has(conclusion);
6187
- }
6188
- function parse_check_run(item) {
6189
- const status2 = read_string(item[KEY_STATUS])?.toLowerCase();
6190
- if (status2 !== "completed") return CHECK_STATUS_PENDING;
6191
- return is_passing_conclusion(item) ? CHECK_STATUS_PASS : CHECK_STATUS_FAIL;
6192
- }
6193
- function parse_rollup_status(item) {
6194
- const type_name = read_string(item[KEY_TYPE_NAME]);
6195
- if (type_name === "StatusContext") return parse_status_context(item);
6196
- return parse_check_run(item);
6197
- }
6198
- function read_rollup_array(parsed) {
6199
- const result = pr_raw_schema.safeParse(parsed);
6200
- if (!result.success) return [];
6201
- return result.data.statusCheckRollup ?? [];
6202
- }
6203
- function parse_rollup_item(item) {
6204
- const name = read_string(item[KEY_NAME]) ?? read_string(item[KEY_CONTEXT]);
6205
- if (name === void 0) return void 0;
6206
- return { name, status: parse_rollup_status(item) };
6207
- }
6208
- function parse_rollup_checks(raw_json) {
6209
- const parsed = json_value.parse_or_undefined(raw_json);
6210
- const rollup = read_rollup_array(parsed);
6211
- const checks = [];
6212
- for (const item of rollup) {
6213
- const parsed_item = parse_rollup_item(item);
6214
- if (parsed_item !== void 0) checks.push(parsed_item);
6215
- }
6216
- return checks;
6217
- }
6218
- function parse_pr_state_snapshot(raw_json) {
6219
- const parsed = json_value.parse_or_undefined(raw_json);
6220
- const result = pr_raw_schema.safeParse(parsed);
6221
- const data = result.success ? result.data : void 0;
6222
- return {
6223
- rollup: parse_rollup_checks(raw_json),
6224
- merge_state_status: read_string(data?.mergeStateStatus),
6225
- review_decision: read_string(data?.reviewDecision)
6226
- };
6227
- }
6228
-
6229
- // scripts/gh/git-pr-checks-eval.ts
6230
- var DEFAULT_REQUIRED_CHECKS = ["SonarQube"];
6231
- var CODERABBIT_CHECK_NAME = "CodeRabbit";
6232
- var REQUIRED_CHECKS_ENV_VAR = "JOSH_REQUIRED_CHECKS";
6233
- function parse_required_checks() {
6234
- const raw = process.env[REQUIRED_CHECKS_ENV_VAR];
6235
- if (!raw) return DEFAULT_REQUIRED_CHECKS;
6236
- return raw.split(",").map((check) => check.trim()).filter((check) => check.length > 0);
6237
- }
6238
- var REQUIRED_CHECKS = parse_required_checks();
6239
- var MERGE_STATE_CLEAN = "CLEAN";
6240
- var MERGE_STATE_UNSTABLE = "UNSTABLE";
6241
- var MERGE_STATE_DIRTY = "DIRTY";
6242
- var REVIEW_CHANGES_REQUESTED2 = "CHANGES_REQUESTED";
6243
- var CHECK_SUITE_SEPARATOR = " / ";
6244
- var FAILURE_MESSAGE_PREFIX = "PR checks failed";
6245
- var FAILURE_REASON_REVIEW = "review requested changes";
6246
- var FAILURE_REASON_CHECKS = "failed checks";
6247
- var FAILURE_REASON_CONFLICT = "merge conflict";
6248
- function is_required_match(check_name, required_name) {
6249
- if (check_name === required_name) return true;
6250
- return check_name.startsWith(`${required_name}${CHECK_SUITE_SEPARATOR}`);
6251
- }
6252
- function find_required_check(checks, required_name) {
6253
- return checks.find((check) => is_required_match(check.name, required_name));
6254
- }
6255
- function read_required_statuses(checks) {
6256
- return REQUIRED_CHECKS.map(
6257
- (name) => find_required_check(checks, name)?.status ?? CHECK_STATUS_MISSING
6258
- );
6259
- }
6260
- function is_review_blocked(review_decision) {
6261
- return review_decision === REVIEW_CHANGES_REQUESTED2;
6262
- }
6263
- function is_merge_conflict(merge_state_status) {
6264
- return merge_state_status === MERGE_STATE_DIRTY;
6265
- }
6266
- function evaluate_failure_state(input) {
6267
- if (is_merge_conflict(input.merge_state_status) || is_review_blocked(input.review_decision) || input.failed_checks.length > 0) {
6268
- return "failure";
6269
- }
6270
- return void 0;
6271
- }
6272
- function is_merge_state_clean(merge_state_status) {
6273
- return merge_state_status === MERGE_STATE_CLEAN;
6274
- }
6275
- function is_every_required_passing(statuses) {
6276
- return statuses.every((status2) => status2 === CHECK_STATUS_PASS);
6277
- }
6278
- function is_coderabbit_check(check_name) {
6279
- return is_required_match(check_name, CODERABBIT_CHECK_NAME);
6280
- }
6281
- function is_unstable_only_from_coderabbit(snapshot) {
6282
- if (snapshot.merge_state_status !== MERGE_STATE_UNSTABLE) return false;
6283
- const non_passing = snapshot.rollup.filter((check) => check.status !== CHECK_STATUS_PASS);
6284
- if (non_passing.length === 0) return false;
6285
- return non_passing.every((check) => is_coderabbit_check(check.name));
6286
- }
6287
- function is_required_check(check_name) {
6288
- return REQUIRED_CHECKS.some((required) => is_required_match(check_name, required));
6289
- }
6290
- function is_blocking_failure(check) {
6291
- if (check.status !== CHECK_STATUS_FAIL) return false;
6292
- return !is_coderabbit_check(check.name) || is_required_check(check.name);
6293
- }
6294
- function collect_blocking_failures(snapshot) {
6295
- return snapshot.rollup.filter((check) => is_blocking_failure(check)).map((check) => check.name);
6296
- }
6297
- function is_mergeable_state(snapshot) {
6298
- if (is_merge_state_clean(snapshot.merge_state_status)) return true;
6299
- return is_unstable_only_from_coderabbit(snapshot);
6300
- }
6301
- function collect_failure_reasons(snapshot) {
6302
- const reasons = [];
6303
- if (is_merge_conflict(snapshot.merge_state_status)) reasons.push(FAILURE_REASON_CONFLICT);
6304
- if (is_review_blocked(snapshot.review_decision)) reasons.push(FAILURE_REASON_REVIEW);
6305
- const failed = collect_blocking_failures(snapshot);
6306
- if (failed.length > 0) reasons.push(`${FAILURE_REASON_CHECKS}: ${failed.join(", ")}`);
6307
- return reasons;
6308
- }
6309
- function describe_pr_failure(snapshot) {
6310
- const reasons = collect_failure_reasons(snapshot);
6311
- if (reasons.length === 0) return `${FAILURE_MESSAGE_PREFIX}.`;
6312
- return `${FAILURE_MESSAGE_PREFIX} (${reasons.join("; ")}).`;
6313
- }
6314
- function evaluate_pr_state(snapshot) {
6315
- const statuses = read_required_statuses(snapshot.rollup);
6316
- const failure = evaluate_failure_state({
6317
- review_decision: snapshot.review_decision,
6318
- failed_checks: collect_blocking_failures(snapshot),
6319
- merge_state_status: snapshot.merge_state_status
6320
- });
6321
- if (failure !== void 0) return failure;
6322
- if (is_mergeable_state(snapshot) && is_every_required_passing(statuses)) {
6323
- return "success";
6324
- }
6325
- return "pending";
6326
- }
6327
- function is_review_decision_decisive(snapshot) {
6328
- return evaluate_pr_state(snapshot) !== "pending";
6329
- }
6330
-
6331
6125
  // scripts/gh/git-pr-checks.ts
6332
6126
  var SECONDS_TO_MS = 1e3;
6333
6127
  var CHECK_WAIT_INTERVAL_MS = 1e4;
@@ -6356,9 +6150,14 @@ var MERGE_GATE_EVALUATOR = {
6356
6150
  function advance_stable_count(previous, state) {
6357
6151
  return state === "success" ? previous + 1 : 0;
6358
6152
  }
6153
+ function failure_error(message, snapshot) {
6154
+ return is_merge_conflict(snapshot.merge_state_status) ? new PrConflictError(message) : new Error(message);
6155
+ }
6359
6156
  function classify_poll_result(input) {
6360
6157
  const state = input.evaluator.evaluate(input.snapshot);
6361
- if (state === "failure") throw new Error(input.evaluator.describe(input.snapshot));
6158
+ if (state === "failure") {
6159
+ throw failure_error(input.evaluator.describe(input.snapshot), input.snapshot);
6160
+ }
6362
6161
  const next_stable_count = advance_stable_count(input.stable_count, state);
6363
6162
  return {
6364
6163
  is_done: next_stable_count >= input.required_stable_reads,
@@ -6509,7 +6308,6 @@ export {
6509
6308
  tail_commands,
6510
6309
  filing_cap,
6511
6310
  CONTEXT_CUT_THRESHOLD,
6512
- RECENT_REQUEST_WINDOW,
6513
6311
  agent_role_profile,
6514
6312
  cli_flags,
6515
6313
  own_session,
@@ -6544,7 +6342,6 @@ export {
6544
6342
  read_json_listing,
6545
6343
  parse_json_object_safe,
6546
6344
  git_gh_exec,
6547
- open_issue_schema,
6548
6345
  git_gh_issue_read,
6549
6346
  git_gh_pr_read,
6550
6347
  git_gh_command
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  lane_child_marker
3
- } from "./chunk-5KTCMCOT.js";
3
+ } from "./chunk-32GQTL4F.js";
4
4
 
5
5
  // scripts/lane/lane-guard-policy.ts
6
6
  var DEFAULT_MODE = "refuse";