@joshuafolkken/kit 1.3092.0 → 1.3099.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 (124) hide show
  1. package/dist/.inputs-verified.json +1 -1
  2. package/dist/commands/backlog-drive-cli.js +17 -17
  3. package/dist/commands/backlogrun-cli.js +21 -20
  4. package/dist/commands/check-related.js +18 -18
  5. package/dist/commands/{chunk-VXE3V3OC.js → chunk-2CNVIA35.js} +2 -2
  6. package/dist/commands/{chunk-374XGAWD.js → chunk-36XHHYNU.js} +1 -1
  7. package/dist/commands/{chunk-W3MDLQZF.js → chunk-3LUPGBW4.js} +1 -1
  8. package/dist/commands/{chunk-T6OUNP7E.js → chunk-3VLDFM5I.js} +6 -6
  9. package/dist/commands/{chunk-4K7KLR7L.js → chunk-6AHAY5VZ.js} +1 -1
  10. package/dist/commands/{chunk-ET6IRQ3L.js → chunk-6FN37DER.js} +3 -3
  11. package/dist/commands/{chunk-LBMAJDGN.js → chunk-6JD4VNO4.js} +2 -2
  12. package/dist/commands/{chunk-KD3SEAMV.js → chunk-7HYYHCTN.js} +2 -2
  13. package/dist/commands/{chunk-4GUGC4IW.js → chunk-7K5ITPHR.js} +2 -2
  14. package/dist/commands/{chunk-XTJA34ND.js → chunk-7ULYLGUK.js} +10 -10
  15. package/dist/commands/{chunk-IEKW3ON6.js → chunk-ABM2MZBF.js} +1 -1
  16. package/dist/commands/{chunk-IOKOHB7P.js → chunk-BBLEC4YQ.js} +1 -1
  17. package/dist/commands/{chunk-V2T5DP3B.js → chunk-C7FGDZWP.js} +1 -1
  18. package/dist/commands/{chunk-MHXIJKGP.js → chunk-EHPTXSAT.js} +20 -9
  19. package/dist/commands/{chunk-PF3PMT2Q.js → chunk-EPICTV2P.js} +1 -1
  20. package/dist/commands/{chunk-GVDRRBHZ.js → chunk-EVVQJJFV.js} +2 -2
  21. package/dist/commands/{chunk-NOSG3RUP.js → chunk-F57LACNC.js} +2 -2
  22. package/dist/commands/{chunk-BAEDHPXW.js → chunk-FA7CN75F.js} +4 -4
  23. package/dist/commands/{chunk-62NYXZCC.js → chunk-FDASVHZD.js} +1 -1
  24. package/dist/commands/{chunk-YMAEYY5R.js → chunk-FEYZ575X.js} +1 -1
  25. package/dist/commands/{chunk-PILH72AV.js → chunk-FTAWHAI7.js} +1 -1
  26. package/dist/commands/{chunk-MK4CARBI.js → chunk-G3BBCAAH.js} +1 -1
  27. package/dist/commands/{chunk-Z6QLFPFB.js → chunk-GABDPTDK.js} +4 -4
  28. package/dist/commands/{chunk-VHLDQ3PH.js → chunk-HHS3LYLV.js} +2 -2
  29. package/dist/commands/{chunk-EE4VOZJP.js → chunk-HQZ65PJE.js} +3 -3
  30. package/dist/commands/{chunk-KHGDZQRG.js → chunk-HSZECERZ.js} +2 -2
  31. package/dist/commands/{chunk-BLUAO4QW.js → chunk-IY3DSDRW.js} +1 -1
  32. package/dist/commands/{chunk-2XZF3YFY.js → chunk-J2RUI4KN.js} +1 -1
  33. package/dist/commands/{chunk-2Q7MGFYB.js → chunk-J3PCRUVY.js} +27 -12
  34. package/dist/commands/{chunk-RDUFVQVJ.js → chunk-JU2MAYQ3.js} +7 -7
  35. package/dist/commands/{chunk-ZEUKX3RZ.js → chunk-KJPZPTS4.js} +1 -1
  36. package/dist/commands/{chunk-7E43YW53.js → chunk-MHF6BDQI.js} +1 -1
  37. package/dist/commands/{chunk-BE6F4YK2.js → chunk-OHN3QARP.js} +10 -10
  38. package/dist/commands/{chunk-AT46EY7H.js → chunk-OKBZGLD5.js} +1 -1
  39. package/dist/commands/{chunk-XCCT6GKA.js → chunk-OZN4HOZT.js} +2 -2
  40. package/dist/commands/{chunk-ZJ5S4VFD.js → chunk-RAQ3E6OT.js} +1 -1
  41. package/dist/commands/{chunk-XSKJAG72.js → chunk-S5GX3H4P.js} +1 -1
  42. package/dist/commands/{chunk-HESWKELD.js → chunk-SC57VV6A.js} +1 -1
  43. package/dist/commands/{chunk-EZYW54OQ.js → chunk-SOETJZWH.js} +221 -118
  44. package/dist/commands/{chunk-HNFBEB4L.js → chunk-UUA63LCI.js} +1 -1
  45. package/dist/commands/{chunk-ZGBXUY7R.js → chunk-UZDKCGDC.js} +1 -1
  46. package/dist/commands/{chunk-B5XYAWNN.js → chunk-VPRQFM2T.js} +1 -1
  47. package/dist/commands/{chunk-M4WG74Q7.js → chunk-VUCDGQ6Y.js} +1 -1
  48. package/dist/commands/{chunk-UX3HCPLX.js → chunk-W7X7MZZN.js} +1 -1
  49. package/dist/commands/{chunk-EN65ZS3S.js → chunk-WORHUJ6T.js} +1 -1
  50. package/dist/commands/chunk-WRHMYSW7.js +36 -0
  51. package/dist/commands/{chunk-K5H3CLZZ.js → chunk-YANDBVAT.js} +1 -1
  52. package/dist/commands/{chunk-GWTBIGYC.js → chunk-YD7XK2TX.js} +1 -1
  53. package/dist/commands/{chunk-M5HA2ZCG.js → chunk-YT5JR2CB.js} +2 -2
  54. package/dist/commands/{chunk-EWCUT7U2.js → chunk-Z2NUK47W.js} +1 -1
  55. package/dist/commands/{chunk-4MGTNY2L.js → chunk-ZI3SABMH.js} +1 -1
  56. package/dist/commands/{chunk-TTTZZN7F.js → chunk-ZJJLROJY.js} +3 -3
  57. package/dist/commands/disposition-cli.js +15 -15
  58. package/dist/commands/git-followup-workflow.js +18 -7
  59. package/dist/commands/inputs.json +1637 -1632
  60. package/dist/commands/issue-already-done-cli.js +8 -8
  61. package/dist/commands/issue-measured-cli.js +9 -9
  62. package/dist/commands/issue-plan-cli.js +16 -16
  63. package/dist/commands/issue-premise-unmet-cli.js +8 -8
  64. package/dist/commands/lane-breakdown-cli.js +17 -17
  65. package/dist/commands/lane-cli.js +20 -20
  66. package/dist/commands/lane-measure-cli.js +23 -23
  67. package/dist/commands/lane-plan-cli.js +15 -15
  68. package/dist/commands/lane-restart-cli.js +20 -20
  69. package/dist/commands/lane-why-cli.js +4 -4
  70. package/dist/commands/lint-parallel-main.js +2 -2
  71. package/dist/commands/lint-related.js +6 -6
  72. package/dist/commands/lint-rule.js +2 -2
  73. package/dist/commands/plan-scaffold-cli.js +20 -20
  74. package/dist/commands/pre-commit-type-check.js +7 -7
  75. package/dist/commands/pre-push-unit.js +9 -9
  76. package/dist/commands/prose-stale-cli.js +5 -5
  77. package/dist/commands/review-brief-main.js +23 -23
  78. package/dist/commands/review-pair-cli.js +19 -19
  79. package/dist/commands/review-record-main.js +19 -19
  80. package/dist/commands/review-round2-cli.js +4 -4
  81. package/dist/commands/review-submit-cli.js +23 -23
  82. package/dist/commands/run-board-main.js +2 -1
  83. package/dist/commands/run-chain-cli.js +19 -19
  84. package/dist/commands/run-cut-cli.js +19 -19
  85. package/dist/commands/run-entry-cli.js +27 -27
  86. package/dist/commands/run-hold-main.js +7 -7
  87. package/dist/commands/run-next-cli.js +20 -20
  88. package/dist/commands/run-park-cli.js +8 -8
  89. package/dist/commands/run-pause-cli.js +8 -8
  90. package/dist/commands/run-prep-main.js +20 -20
  91. package/dist/commands/run-prime-cli.js +10 -10
  92. package/dist/commands/run-review-cli.js +26 -26
  93. package/dist/commands/run-ship-cli.js +29 -29
  94. package/dist/commands/run-ship-evidence-cli.js +4 -4
  95. package/dist/commands/run-ship-wait-main.js +5 -5
  96. package/dist/commands/run-split-cli.js +8 -8
  97. package/dist/commands/run-step-cli.js +27 -27
  98. package/dist/commands/run-wake-main.js +19 -19
  99. package/dist/commands/selfcheck-cli.js +8 -8
  100. package/dist/commands/stop-guard.js +7 -7
  101. package/dist/commands/test-e2e-guard.js +6 -6
  102. package/dist/commands/test-pinned-main.js +8 -8
  103. package/dist/commands/test-reach-cli.js +4 -4
  104. package/dist/commands/{test-related-Z6YY2GFH.js → test-related-XBDH2IOH.js} +11 -11
  105. package/dist/commands/test-related-main.js +13 -13
  106. package/dist/commands/verification-gate.js +17 -17
  107. package/dist/hooks/inputs.json +571 -570
  108. package/dist/hooks/stop-guard.js +68 -59
  109. package/dist/inputs.json +78 -78
  110. package/package.json +1 -1
  111. package/scripts/followup/git-followup-finish.ts +16 -1
  112. package/scripts/gate/verification-inputs.ts +2 -1
  113. package/scripts/run/board/run-board-layout.ts +9 -4
  114. package/scripts/run/board/run-board-read.ts +29 -69
  115. package/scripts/run/board/run-board-render-lanes.ts +26 -9
  116. package/scripts/run/board/run-board-render-lead.ts +9 -0
  117. package/scripts/run/board/run-board-root-layout.ts +69 -0
  118. package/scripts/run/board/run-board-single.ts +69 -4
  119. package/scripts/run/board/run-board-span-read.ts +85 -0
  120. package/scripts/run/board/run-board-tick.ts +12 -4
  121. package/scripts/run/hold/run-hold-ended.ts +50 -0
  122. package/scripts/test/test-pinned-cache-logic.ts +13 -7
  123. package/scripts/test/test-pinned-cache.ts +33 -11
  124. package/scripts/test/test-runner-config.ts +19 -0
@@ -48,6 +48,9 @@ import {
48
48
  import {
49
49
  ts_entry_loader
50
50
  } from "./chunk-VHRNXWVP.js";
51
+ import {
52
+ run_hold_ended
53
+ } from "./chunk-WRHMYSW7.js";
51
54
  import {
52
55
  git_gh_issue_alias_graphql
53
56
  } from "./chunk-XAEL24EG.js";
@@ -1985,7 +1988,7 @@ function rows_of2(layout) {
1985
1988
  return [...layout.active, ...queued_rows(layout), ...layout.people, ...layout.unreached];
1986
1989
  }
1987
1990
  function drawn_rows(layout) {
1988
- return [...rows_of2(layout), ...layout.earlier ?? []];
1991
+ return [layout.root?.row ?? [], rows_of2(layout), layout.earlier ?? []].flat();
1989
1992
  }
1990
1993
  function people_of(layout) {
1991
1994
  const asked = layout.active.filter((row) => row.state === "human");
@@ -1993,7 +1996,7 @@ function people_of(layout) {
1993
1996
  }
1994
1997
  function lane_rows(layout, apart) {
1995
1998
  const own = layout.active.filter((row) => !apart.includes(row));
1996
- return [...own, ...layout.earlier ?? []];
1999
+ return [layout.root?.row ?? [], own, layout.earlier ?? []].flat();
1997
2000
  }
1998
2001
  function lanes_drawn(layout) {
1999
2002
  const finished = layout.active.filter((row) => is_finished(row.state));
@@ -2005,6 +2008,7 @@ function listed_parks(layout) {
2005
2008
  }
2006
2009
  var run_board_layout = {
2007
2010
  EMPTY_LAYOUT,
2011
+ active_order,
2008
2012
  drawn_rows,
2009
2013
  is_blocked,
2010
2014
  is_decision: run_board_human.is_decision,
@@ -2229,8 +2233,8 @@ function command_target(command) {
2229
2233
  }
2230
2234
  function path_target(file_path, root) {
2231
2235
  const relative = root === void 0 ? void 0 : path.relative(root, path.resolve(root, file_path));
2232
- const is_inside = relative !== void 0 && !relative.startsWith("..") && relative !== "";
2233
- return ascii_head(is_inside ? relative : path.basename(file_path));
2236
+ const is_inside2 = relative !== void 0 && !relative.startsWith("..") && relative !== "";
2237
+ return ascii_head(is_inside2 ? relative : path.basename(file_path));
2234
2238
  }
2235
2239
  function shown(target) {
2236
2240
  return target === "" ? void 0 : target;
@@ -4157,8 +4161,13 @@ var SPACE = 1;
4157
4161
  var ELAPSED_START = LANE_INDENT.length + PROGRESS_WIDTH + SPACE + ICON_WIDTH + SPACE + TIME_WIDTH + SPACE;
4158
4162
  var USAGE_START = ELAPSED_START + TIME_WIDTH + SPACE;
4159
4163
  var LANES_LABEL = `${run_board_labels.LANES_ICON} lanes`;
4164
+ var SINGLE_RUN_ICON = "\u{1F3E0}";
4160
4165
  var RULE_ROOM = 6;
4166
+ function root_label(run_name) {
4167
+ return `${SINGLE_RUN_ICON} ${run_name}`;
4168
+ }
4161
4169
  function lane_label(header) {
4170
+ if (header.run_name !== void 0) return root_label(header.run_name);
4162
4171
  if (header.occupied_count === void 0) return LANES_LABEL;
4163
4172
  return `${LANES_LABEL} ${String(header.occupied_count)}/${String(header.lane_limit ?? "\u2014")}`;
4164
4173
  }
@@ -4199,6 +4208,7 @@ var run_board_render_lead = {
4199
4208
  indent_of,
4200
4209
  lead_of,
4201
4210
  lane_label,
4211
+ root_label,
4202
4212
  running_fresh
4203
4213
  };
4204
4214
 
@@ -4350,7 +4360,7 @@ var run_board_usage_text = {
4350
4360
  var { HEADER_ICONS: HEADER_ICONS6 } = run_board_labels;
4351
4361
  var { cell_widths: cell_widths2, cells_of: cells_of2, lane_limits: lane_limits2 } = run_board_usage_text;
4352
4362
  var { columns_rule: columns_rule2 } = run_board_render_section;
4353
- var { ELAPSED_START: ELAPSED_START2, LANES_LABEL: LANES_LABEL2, USAGE_START: USAGE_START2, column_offset: column_offset2, lane_label: lane_label2 } = run_board_render_lead;
4363
+ var { ELAPSED_START: ELAPSED_START2, LANES_LABEL: LANES_LABEL2, USAGE_START: USAGE_START2, column_offset: column_offset2, lane_label: lane_label2, root_label: root_label2 } = run_board_render_lead;
4354
4364
  var { width_of: width_of3 } = run_board_fit;
4355
4365
  var { columns_cut: columns_cut3 } = run_board_render_title;
4356
4366
  var { reasons_of: reasons_of2 } = run_board_seat;
@@ -4418,16 +4428,23 @@ function seat_lines(header, columns) {
4418
4428
  is_seat: true
4419
4429
  }));
4420
4430
  }
4421
- function lanes_section(rows, cells, header, columns) {
4422
- const lines = [...rows, ...seat_lines(header, columns)];
4431
+ function rows_section(lines, label, cells, header) {
4423
4432
  if (lines.length === 0) return [];
4424
4433
  const offset = column_offset2(header);
4425
- const label = lane_label2(header);
4426
4434
  const elapsed = { label: HEADER_ICONS6.elapsed, start: ELAPSED_START2 + offset };
4427
4435
  const usage = cells === void 0 ? [] : label_columns(USAGE_START2 + offset, cells.gauge);
4428
4436
  const rule = columns_rule2(label, [elapsed, ...usage]);
4429
4437
  return [{ head: ["", rule], lines, label, key: "lanes" }];
4430
4438
  }
4439
+ function lanes_section(rows, cells, header, columns) {
4440
+ const root = header.layout?.root;
4441
+ const root_count = root === void 0 ? 0 : 1;
4442
+ const lanes = [...rows.slice(root_count), ...seat_lines(header, columns)];
4443
+ return [
4444
+ ...rows_section(rows.slice(0, root_count), root_label2(root?.name ?? ""), cells, header),
4445
+ ...rows_section(lanes, lane_label2(header), cells, header)
4446
+ ];
4447
+ }
4431
4448
  var run_board_render_lanes = {
4432
4449
  COLUMN_LABELS,
4433
4450
  LANES_LABEL: LANES_LABEL2,
@@ -4806,7 +4823,7 @@ function entry_lines(entry, frame) {
4806
4823
  if (entry.kind === "row") return [row_line(ROW_INDENT3, entry.row, frame)];
4807
4824
  return epic_lines(entry, frame);
4808
4825
  }
4809
- function rows_section(heading, rows, frame, stage) {
4826
+ function rows_section2(heading, rows, frame, stage) {
4810
4827
  return plan_section2(
4811
4828
  heading,
4812
4829
  rows.map((row) => row_line(ROW_INDENT3, row, frame, stage))
@@ -4850,7 +4867,7 @@ function active_sections(layout, frame) {
4850
4867
  frame.header,
4851
4868
  frame.columns
4852
4869
  );
4853
- const plan = [...lanes, ...rows_section(decision, people, frame)];
4870
+ const plan = [...lanes, ...rows_section2(decision, people, frame)];
4854
4871
  return { plan, rule_width: rule_width(lead, { ...lane_frame, shared }) };
4855
4872
  }
4856
4873
  function plan_parts(header, notes, size) {
@@ -4864,7 +4881,7 @@ function plan_parts(header, notes, size) {
4864
4881
  ...active_sections(layout, frame),
4865
4882
  below: [
4866
4883
  ...keyed2("queued", queued_section(layout, frame)),
4867
- ...keyed2("waiting", rows_section(waiting, layout.unreached, conditioned, "waiting")),
4884
+ ...keyed2("waiting", rows_section2(waiting, layout.unreached, conditioned, "waiting")),
4868
4885
  ...done_section2(done, (row) => row_line(ROW_INDENT3, row, conditioned))
4869
4886
  ]
4870
4887
  };
@@ -4892,6 +4909,40 @@ var run_board_render = {
4892
4909
  render_no_run: run_board_render_none.render_no_run
4893
4910
  };
4894
4911
 
4912
+ // scripts/run/board/run-board-root-layout.ts
4913
+ function live_of(local, read5) {
4914
+ const { root } = local;
4915
+ if (root === void 0) return {};
4916
+ const status = run_board_status.statuses_of(root.events, local.lane_states).get(root.issue);
4917
+ if (status === void 0) return {};
4918
+ const statuses = /* @__PURE__ */ new Map([[root.issue, status]]);
4919
+ const [row] = run_board_layout.local_layout_of(statuses, void 0, read5).active;
4920
+ return row === void 0 ? {} : { root: { name: root.command, row } };
4921
+ }
4922
+ function ended_status(run2) {
4923
+ return { state: "merged", started_ms: run2.started_ms, ended_ms: run2.ended_ms };
4924
+ }
4925
+ function active_of(active, ended2, read5) {
4926
+ if (ended2.length === 0) return active;
4927
+ const statuses = new Map(ended2.map((run2) => [run2.issue, ended_status(run2)]));
4928
+ const rows = run_board_layout.local_layout_of(statuses, void 0, read5).active;
4929
+ const kept = active.filter((row) => !statuses.has(row.number));
4930
+ return [...kept, ...rows].toSorted(run_board_layout.active_order);
4931
+ }
4932
+ function layout_of3(layout, local, read5) {
4933
+ return {
4934
+ ...layout,
4935
+ active: active_of(layout.active, local.ended_roots ?? [], read5),
4936
+ ...live_of(local, read5)
4937
+ };
4938
+ }
4939
+ function baseline_of(baseline_total, run_layout, layout) {
4940
+ if (baseline_total === void 0) return void 0;
4941
+ const { rows_of: rows_of6 } = run_board_layout;
4942
+ return baseline_total + rows_of6(layout).length - rows_of6(run_layout).length;
4943
+ }
4944
+ var run_board_root_layout = { baseline_of, layout_of: layout_of3 };
4945
+
4895
4946
  // scripts/run/board/run-board-spin.ts
4896
4947
  var SPOT = "\uE000";
4897
4948
  var REDRAW_MS = MS_PER_SECOND;
@@ -5253,10 +5304,17 @@ function draw(ports, lines) {
5253
5304
  `);
5254
5305
  }
5255
5306
  function draw_run(state, local, redraw) {
5256
- const layout = layout_for(state, local, redraw.now_ms);
5257
- const first_total = state.plan === void 0 ? void 0 : run_board_header.counts_of(layout).total;
5307
+ const read5 = closed_under(known_of2(state), state.closed);
5308
+ const run_layout = layout_for(state, local, redraw.now_ms);
5309
+ const layout = run_board_root_layout.layout_of(run_layout, local, read5);
5310
+ const first_total = state.plan === void 0 ? void 0 : run_board_header.counts_of(run_layout).total;
5258
5311
  const settled2 = { ...state, baseline_total: state.baseline_total ?? first_total };
5259
- const { lines, spots } = frame_of2(settled2, local, layout, redraw);
5312
+ const baseline_total = run_board_root_layout.baseline_of(
5313
+ settled2.baseline_total,
5314
+ run_layout,
5315
+ layout
5316
+ );
5317
+ const { lines, spots } = frame_of2({ ...settled2, baseline_total }, local, layout, redraw);
5260
5318
  draw(redraw.ports, lines);
5261
5319
  return { ...settled2, spots };
5262
5320
  }
@@ -6177,39 +6235,56 @@ function read3(sources, read_tail = transcript_tail.read_tail) {
6177
6235
  }
6178
6236
  var run_board_operation_read = { TAIL_BYTES, read: read3 };
6179
6237
 
6180
- // scripts/run/board/run-board-roots.ts
6181
- function root_of2(pid, start2, is_same) {
6182
- return is_same(pid, start2) === false ? void 0 : pid;
6238
+ // scripts/run/board/run-board-span.ts
6239
+ var { moment_of } = run_event_scope;
6240
+ function provider_of(record) {
6241
+ return record.scheduler_provider === void 0 ? {} : { scheduler_provider: record.scheduler_provider };
6183
6242
  }
6184
- function supervisor_of(repository, is_same) {
6185
- const wake = run_wake.read_wake(run_wake.wake_path(repository));
6186
- return wake === void 0 ? void 0 : root_of2(wake.pid, wake.process_start, is_same);
6243
+ function ended_span(ended2) {
6244
+ if (ended2 === void 0) return void 0;
6245
+ const started_ms = moment_of(ended2.started_at);
6246
+ const ended_ms = moment_of(ended2.ended_at);
6247
+ if (started_ms === void 0 || ended_ms === void 0) return void 0;
6248
+ return { invocation: ended2.invocation, started_ms, ended_ms, ...provider_of(ended2) };
6187
6249
  }
6188
- function parent_of(read5, is_same) {
6189
- if (read5.kind !== "carried") return void 0;
6190
- return root_of2(read5.carry.owner_pid, read5.carry.owner_start, is_same);
6250
+ function launch_span(launch2) {
6251
+ const started_ms = launch2 === void 0 ? void 0 : moment_of(launch2.started_at);
6252
+ if (launch2 === void 0 || started_ms === void 0) return void 0;
6253
+ return { invocation: launch2.invocation, started_ms, ended_ms: void 0, ...provider_of(launch2) };
6191
6254
  }
6192
- function roots_of(repository, read5, is_same = process_identity.is_same_process) {
6193
- return { supervisor: supervisor_of(repository, is_same), parent: parent_of(read5, is_same) };
6255
+ function idle_span(ended2, launch2) {
6256
+ const last = ended_span(ended2);
6257
+ const coming = launch_span(launch2);
6258
+ if (coming === void 0) return last;
6259
+ return (last?.ended_ms ?? 0) >= coming.started_ms ? last : coming;
6194
6260
  }
6195
- function is_session_owner(read5) {
6196
- return read5.kind === "carried" && read5.carry.is_handed_off !== true;
6261
+ function span_of6(read5, ended2, launch2) {
6262
+ if (read5.kind !== "carried") return read5.kind === "none" ? idle_span(ended2, launch2) : void 0;
6263
+ const started_ms = moment_of(read5.carry.started_at);
6264
+ if (started_ms === void 0) return void 0;
6265
+ return {
6266
+ invocation: read5.carry.invocation,
6267
+ started_ms,
6268
+ ended_ms: void 0,
6269
+ ...provider_of(read5.carry)
6270
+ };
6197
6271
  }
6198
- function live_session_pid(pid, start2, wake, is_same) {
6199
- return pid !== void 0 && pid !== wake?.pid && is_same(pid, start2) !== false;
6272
+ function is_ended_drawn(ended2, launch2) {
6273
+ return idle_span(ended2, launch2)?.ended_ms !== void 0;
6200
6274
  }
6201
- function session_is_active(repository, read5, is_same) {
6202
- if (read5.kind !== "carried" || !is_session_owner(read5)) return false;
6203
- const wake = run_wake.read_wake(run_wake.wake_path(repository));
6204
- const pid = read5.carry.owner_pid ?? wake?.woke_pid;
6205
- return live_session_pid(pid, read5.carry.owner_start, wake, is_same);
6275
+ function resume_of(read5, ended2, launch2) {
6276
+ if (read5.kind !== "none" || !is_ended_drawn(ended2, launch2)) return void 0;
6277
+ return ended2?.stopped === void 0 ? void 0 : ended2.session;
6206
6278
  }
6207
- async function same_in(table) {
6208
- const rows = table === void 0 ? void 0 : await table();
6209
- const read5 = lane_process_table.start_reader(rows ?? []);
6210
- return (pid, start2) => process_identity.is_same_process(pid, start2, read5);
6279
+ function is_within(event, span) {
6280
+ const at = moment_of(event.at);
6281
+ if (at === void 0 || at < span.started_ms) return false;
6282
+ return span.ended_ms === void 0 || at <= span.ended_ms;
6211
6283
  }
6212
- var run_board_roots = { roots_of, same_in, session_is_active };
6284
+ function events_of(events, span) {
6285
+ return events.filter((event) => is_within(event, span));
6286
+ }
6287
+ var run_board_span = { events_of, resume_of, span_of: span_of6 };
6213
6288
 
6214
6289
  // scripts/run/board/run-board-single.ts
6215
6290
  var FULLRUN = "fullrun";
@@ -6221,7 +6296,7 @@ function is_running(read5) {
6221
6296
  if (read5.kind !== "held") return false;
6222
6297
  return issue_number_shape.is_issue_number(read5.hold.issue) && !run_hold.is_stop_marked(read5.hold);
6223
6298
  }
6224
- function span_of6(read5) {
6299
+ function span_of7(read5) {
6225
6300
  if (!is_running(read5)) return void 0;
6226
6301
  const started_ms = run_event_scope.moment_of(read5.hold.taken_at);
6227
6302
  if (started_ms === void 0) return void 0;
@@ -6248,7 +6323,26 @@ async function span_here(is_carried) {
6248
6323
  if (is_carried && lane_paths.lane_issue_of(process.cwd()) !== void 0) return void 0;
6249
6324
  const directory = await directory_here();
6250
6325
  if (directory === void 0) return void 0;
6251
- return span_of6(run_hold.read_hold(run_hold.hold_path(directory)));
6326
+ return span_of7(run_hold.read_hold(run_hold.hold_path(directory)));
6327
+ }
6328
+ function ended_of3(ended2) {
6329
+ if (!issue_number_shape.is_issue_number(ended2.issue)) return void 0;
6330
+ const started_ms = run_event_scope.moment_of(ended2.taken_at);
6331
+ const ended_ms = run_event_scope.moment_of(ended2.ended_at);
6332
+ if (started_ms === void 0 || ended_ms === void 0) return void 0;
6333
+ const command = ended2.is_fullrun === true ? FULLRUN : HALFRUN;
6334
+ return { command, issue: Number(ended2.issue), started_ms, ended_ms };
6335
+ }
6336
+ function is_inside(run2, span) {
6337
+ return run2.ended_ms >= span.started_ms && run2.ended_ms <= (span.ended_ms ?? Infinity);
6338
+ }
6339
+ function ended_in(records, span) {
6340
+ return records.map((record) => ended_of3(record)).filter((run2) => run2 !== void 0 && is_inside(run2, span));
6341
+ }
6342
+ async function ended_here(span) {
6343
+ const directory = await directory_here();
6344
+ if (directory === void 0) return [];
6345
+ return ended_in(run_hold_ended.read_ended(run_hold_ended.ended_path(directory)), span);
6252
6346
  }
6253
6347
  function single_of(invocation) {
6254
6348
  const { command, issue } = SINGLE_INVOCATION.exec(invocation)?.groups ?? {};
@@ -6259,7 +6353,7 @@ function scope_of(invocation) {
6259
6353
  const single = single_of(invocation);
6260
6354
  return single === void 0 ? void 0 : { issues: [single.issue], only: true };
6261
6355
  }
6262
- function events_of(span, events) {
6356
+ function events_of2(span, events) {
6263
6357
  const single = single_of(span.invocation);
6264
6358
  if (single === void 0) return events;
6265
6359
  const launch2 = {
@@ -6273,7 +6367,21 @@ function events_of(span, events) {
6273
6367
  function name_of4(invocation) {
6274
6368
  return single_of(invocation)?.command;
6275
6369
  }
6276
- var run_board_single = { events_of, name_of: name_of4, scope_of, span_here, span_of: span_of6 };
6370
+ function root_of2(span, events) {
6371
+ const single = single_of(span.invocation);
6372
+ if (single === void 0) return void 0;
6373
+ return { ...single, events: events_of2(span, run_board_span.events_of(events, span)) };
6374
+ }
6375
+ var run_board_single = {
6376
+ ended_here,
6377
+ ended_in,
6378
+ events_of: events_of2,
6379
+ name_of: name_of4,
6380
+ root_of: root_of2,
6381
+ scope_of,
6382
+ span_here,
6383
+ span_of: span_of7
6384
+ };
6277
6385
 
6278
6386
  // scripts/run/board/run-board-scope.ts
6279
6387
  function scope_of2(invocation, added) {
@@ -6284,56 +6392,77 @@ function scope_of2(invocation, added) {
6284
6392
  }
6285
6393
  var run_board_scope = { scope_of: scope_of2 };
6286
6394
 
6287
- // scripts/run/board/run-board-span.ts
6288
- var { moment_of } = run_event_scope;
6289
- function provider_of(record) {
6290
- return record.scheduler_provider === void 0 ? {} : { scheduler_provider: record.scheduler_provider };
6395
+ // scripts/run/board/run-board-roots.ts
6396
+ function root_of3(pid, start2, is_same) {
6397
+ return is_same(pid, start2) === false ? void 0 : pid;
6291
6398
  }
6292
- function ended_span(ended2) {
6293
- if (ended2 === void 0) return void 0;
6294
- const started_ms = moment_of(ended2.started_at);
6295
- const ended_ms = moment_of(ended2.ended_at);
6296
- if (started_ms === void 0 || ended_ms === void 0) return void 0;
6297
- return { invocation: ended2.invocation, started_ms, ended_ms, ...provider_of(ended2) };
6399
+ function supervisor_of(repository, is_same) {
6400
+ const wake = run_wake.read_wake(run_wake.wake_path(repository));
6401
+ return wake === void 0 ? void 0 : root_of3(wake.pid, wake.process_start, is_same);
6298
6402
  }
6299
- function launch_span(launch2) {
6300
- const started_ms = launch2 === void 0 ? void 0 : moment_of(launch2.started_at);
6301
- if (launch2 === void 0 || started_ms === void 0) return void 0;
6302
- return { invocation: launch2.invocation, started_ms, ended_ms: void 0, ...provider_of(launch2) };
6403
+ function parent_of(read5, is_same) {
6404
+ if (read5.kind !== "carried") return void 0;
6405
+ return root_of3(read5.carry.owner_pid, read5.carry.owner_start, is_same);
6303
6406
  }
6304
- function idle_span(ended2, launch2) {
6305
- const last = ended_span(ended2);
6306
- const coming = launch_span(launch2);
6307
- if (coming === void 0) return last;
6308
- return (last?.ended_ms ?? 0) >= coming.started_ms ? last : coming;
6407
+ function roots_of(repository, read5, is_same = process_identity.is_same_process) {
6408
+ return { supervisor: supervisor_of(repository, is_same), parent: parent_of(read5, is_same) };
6309
6409
  }
6310
- function span_of7(read5, ended2, launch2) {
6311
- if (read5.kind !== "carried") return read5.kind === "none" ? idle_span(ended2, launch2) : void 0;
6312
- const started_ms = moment_of(read5.carry.started_at);
6313
- if (started_ms === void 0) return void 0;
6314
- return {
6315
- invocation: read5.carry.invocation,
6316
- started_ms,
6317
- ended_ms: void 0,
6318
- ...provider_of(read5.carry)
6319
- };
6410
+ function is_session_owner(read5) {
6411
+ return read5.kind === "carried" && read5.carry.is_handed_off !== true;
6320
6412
  }
6321
- function is_ended_drawn(ended2, launch2) {
6322
- return idle_span(ended2, launch2)?.ended_ms !== void 0;
6413
+ function live_session_pid(pid, start2, wake, is_same) {
6414
+ return pid !== void 0 && pid !== wake?.pid && is_same(pid, start2) !== false;
6323
6415
  }
6324
- function resume_of(read5, ended2, launch2) {
6325
- if (read5.kind !== "none" || !is_ended_drawn(ended2, launch2)) return void 0;
6326
- return ended2?.stopped === void 0 ? void 0 : ended2.session;
6416
+ function session_is_active(repository, read5, is_same) {
6417
+ if (read5.kind !== "carried" || !is_session_owner(read5)) return false;
6418
+ const wake = run_wake.read_wake(run_wake.wake_path(repository));
6419
+ const pid = read5.carry.owner_pid ?? wake?.woke_pid;
6420
+ return live_session_pid(pid, read5.carry.owner_start, wake, is_same);
6327
6421
  }
6328
- function is_within(event, span) {
6329
- const at = moment_of(event.at);
6330
- if (at === void 0 || at < span.started_ms) return false;
6331
- return span.ended_ms === void 0 || at <= span.ended_ms;
6422
+ async function same_in(table) {
6423
+ const rows = table === void 0 ? void 0 : await table();
6424
+ const read5 = lane_process_table.start_reader(rows ?? []);
6425
+ return (pid, start2) => process_identity.is_same_process(pid, start2, read5);
6332
6426
  }
6333
- function events_of2(events, span) {
6334
- return events.filter((event) => is_within(event, span));
6427
+ var run_board_roots = { roots_of, same_in, session_is_active };
6428
+
6429
+ // scripts/run/board/run-board-span-read.ts
6430
+ var NO_SPAN = {
6431
+ span: void 0,
6432
+ resume: void 0,
6433
+ transcript: void 0,
6434
+ roots: {},
6435
+ carry: void 0,
6436
+ is_stranded: false,
6437
+ is_session_active: false
6438
+ };
6439
+ async function recorded_span_here(repository, table, read5) {
6440
+ const ended2 = run_carry_ended.read_ended(run_carry_ended.ended_path(repository));
6441
+ const launch2 = backlogrun_launch.pending_launch(repository);
6442
+ const span = run_board_span.span_of(read5, ended2, launch2);
6443
+ if (span === void 0) return NO_SPAN;
6444
+ const same_process = await run_board_roots.same_in(table);
6445
+ const stranded_ports = run_stranded_detect.ports_with(same_process);
6446
+ return {
6447
+ span,
6448
+ resume: run_board_span.resume_of(read5, ended2, launch2),
6449
+ transcript: read5.kind === "carried" ? read5.carry.owner_transcript : void 0,
6450
+ roots: run_board_roots.roots_of(repository, read5, same_process),
6451
+ is_session_active: run_board_roots.session_is_active(repository, read5, same_process),
6452
+ carry: read5.kind === "carried" ? read5.carry : void 0,
6453
+ is_stranded: run_stranded_detect.is_stranded_at(repository, stranded_ports)
6454
+ };
6455
+ }
6456
+ async function span_here2(repository, table) {
6457
+ if (repository === void 0) return NO_SPAN;
6458
+ const read5 = run_carry.read_carry(run_carry.carry_path(repository));
6459
+ const is_carried = read5.kind !== "none";
6460
+ const single = await run_board_single.span_here(is_carried);
6461
+ if (single === void 0) return await recorded_span_here(repository, table, read5);
6462
+ const recorded2 = is_carried ? await recorded_span_here(repository, table, read5) : NO_SPAN;
6463
+ return recorded2.span === void 0 ? { ...NO_SPAN, span: single } : { ...recorded2, root: single };
6335
6464
  }
6336
- var run_board_span = { events_of: events_of2, resume_of, span_of: span_of7 };
6465
+ var run_board_span_read = { span_here: span_here2 };
6337
6466
 
6338
6467
  // scripts/run/board/run-board-throughput.ts
6339
6468
  var KIND10 = run_event_stream.EVENT_KIND;
@@ -6474,15 +6603,6 @@ function usual_of(entries, now_ms) {
6474
6603
  var run_board_usual = { usual_of };
6475
6604
 
6476
6605
  // scripts/run/board/run-board-read.ts
6477
- var NO_SPAN = {
6478
- span: void 0,
6479
- resume: void 0,
6480
- transcript: void 0,
6481
- roots: {},
6482
- carry: void 0,
6483
- is_stranded: false,
6484
- is_session_active: false
6485
- };
6486
6606
  var main_roots = stamped_memo.create();
6487
6607
  async function main_root() {
6488
6608
  try {
@@ -6496,28 +6616,6 @@ async function main_root() {
6496
6616
  throw error;
6497
6617
  }
6498
6618
  }
6499
- async function recorded_span_here(repository, table, read5) {
6500
- const ended2 = run_carry_ended.read_ended(run_carry_ended.ended_path(repository));
6501
- const launch2 = backlogrun_launch.pending_launch(repository);
6502
- const span = run_board_span.span_of(read5, ended2, launch2);
6503
- if (span === void 0) return NO_SPAN;
6504
- const same_process = await run_board_roots.same_in(table);
6505
- const stranded_ports = run_stranded_detect.ports_with(same_process);
6506
- return {
6507
- span,
6508
- resume: run_board_span.resume_of(read5, ended2, launch2),
6509
- transcript: read5.kind === "carried" ? read5.carry.owner_transcript : void 0,
6510
- roots: run_board_roots.roots_of(repository, read5, same_process),
6511
- is_session_active: run_board_roots.session_is_active(repository, read5, same_process),
6512
- carry: read5.kind === "carried" ? read5.carry : void 0,
6513
- is_stranded: run_stranded_detect.is_stranded_at(repository, stranded_ports)
6514
- };
6515
- }
6516
- async function span_here2(repository, table) {
6517
- const read5 = run_carry.read_carry(run_carry.carry_path(repository));
6518
- const single = await run_board_single.span_here(read5.kind !== "none");
6519
- return single === void 0 ? await recorded_span_here(repository, table, read5) : { ...NO_SPAN, span: single };
6520
- }
6521
6619
  function sources_of2(repository, lanes, transcript) {
6522
6620
  const root = process.cwd();
6523
6621
  return {
@@ -6593,9 +6691,10 @@ async function span_events_here(events, span, table, carry) {
6593
6691
  ...usage_reset_here(events, carry)
6594
6692
  };
6595
6693
  }
6596
- function span_fields(span) {
6694
+ function span_fields(span, root) {
6597
6695
  const run_name = run_board_single.name_of(span.invocation);
6598
6696
  const times = {
6697
+ ...root,
6599
6698
  started_ms: span.started_ms,
6600
6699
  ended_ms: span.ended_ms,
6601
6700
  ...run_name !== void 0 && { run_name }
@@ -6603,15 +6702,19 @@ function span_fields(span) {
6603
6702
  if (span.scheduler_provider === void 0) return times;
6604
6703
  return { ...times, scheduler_provider: span.scheduler_provider === "openai" ? "codex" : "claude" };
6605
6704
  }
6705
+ async function roots_here(span, root, events) {
6706
+ const ended_roots = await run_board_single.ended_here(span);
6707
+ return root === void 0 ? { ended_roots } : { root: run_board_single.root_of(root, events), ended_roots };
6708
+ }
6606
6709
  async function read_local(table) {
6607
6710
  const repository = await run_carry.repository_directory();
6608
- const { span, resume, transcript, roots, carry, is_stranded, is_session_active } = repository === void 0 ? NO_SPAN : await span_here2(repository, table);
6711
+ const { span, root, resume, transcript, roots, carry, is_stranded, is_session_active } = await run_board_span_read.span_here(repository, table);
6609
6712
  if (repository === void 0 || span === void 0) return void 0;
6610
6713
  const events = run_event_tail.read_events(run_event_stream.target_of(repository));
6611
6714
  const lanes = await lane_registry.list_lanes(await main_root());
6612
6715
  const lane_read = await lanes_here(lanes, repository, events, span.started_ms);
6613
6716
  return {
6614
- ...span_fields(span),
6717
+ ...span_fields(span, await roots_here(span, root, events)),
6615
6718
  scope: run_board_scope.scope_of(span.invocation, carry?.added),
6616
6719
  ...await span_events_here(events, span, table, carry),
6617
6720
  throughput: run_board_throughput.rows_of(events, Date.now()),
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-2WRDAQPJ.js";
4
4
  import {
5
5
  run_hold_cli
6
- } from "./chunk-GWTBIGYC.js";
6
+ } from "./chunk-YD7XK2TX.js";
7
7
  import {
8
8
  cli_body
9
9
  } from "./chunk-7IZJ5MG2.js";
@@ -16,7 +16,7 @@ import {
16
16
  } from "./chunk-PBAEJ5PT.js";
17
17
  import {
18
18
  review_stamps
19
- } from "./chunk-XSKJAG72.js";
19
+ } from "./chunk-S5GX3H4P.js";
20
20
  import {
21
21
  gate_tree
22
22
  } from "./chunk-R36VZIKU.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  lane_plan_check
3
- } from "./chunk-TTTZZN7F.js";
3
+ } from "./chunk-ZJJLROJY.js";
4
4
  import {
5
5
  plan_consumers_section
6
6
  } from "./chunk-SRG6PKVS.js";
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-6O45F6YI.js";
13
13
  import {
14
14
  verification_inputs
15
- } from "./chunk-MHXIJKGP.js";
15
+ } from "./chunk-EHPTXSAT.js";
16
16
  import {
17
17
  lint_shard
18
18
  } from "./chunk-ZECFKW7D.js";
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-2E6PSONB.js";
13
13
  import {
14
14
  issue_measured_close
15
- } from "./chunk-PF3PMT2Q.js";
15
+ } from "./chunk-EPICTV2P.js";
16
16
  import {
17
17
  epic_validate
18
18
  } from "./chunk-RFWB2KAV.js";
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-U7Y6RKLK.js";
8
8
  import {
9
9
  review_code_tree
10
- } from "./chunk-62NYXZCC.js";
10
+ } from "./chunk-FDASVHZD.js";
11
11
  import {
12
12
  test_declared_logic
13
13
  } from "./chunk-7HCPRVMB.js";
@@ -0,0 +1,36 @@
1
+ import {
2
+ stamp_file
3
+ } from "./chunk-VLN6TSPJ.js";
4
+ import {
5
+ json_value
6
+ } from "./chunk-HIU2WXB6.js";
7
+
8
+ // scripts/run/hold/run-hold-ended.ts
9
+ import { z } from "zod";
10
+ var ENDED_PREFIX = "josh-run-hold-ended-";
11
+ var KEPT_RUNS = 20;
12
+ var ended_hold_schema = z.object({
13
+ issue: z.string(),
14
+ is_fullrun: z.boolean().optional(),
15
+ taken_at: z.string(),
16
+ ended_at: z.string()
17
+ });
18
+ function ended_path(git_directory) {
19
+ return stamp_file.stamp_path(ENDED_PREFIX, git_directory);
20
+ }
21
+ function read_ended(target) {
22
+ const raw = stamp_file.read_stamp_text(target);
23
+ return raw === void 0 ? [] : json_value.parse_with(raw, z.array(ended_hold_schema)) ?? [];
24
+ }
25
+ function record_ended(target, read, now = /* @__PURE__ */ new Date()) {
26
+ if (read.kind !== "held") return;
27
+ const { issue, is_fullrun, taken_at } = read.hold;
28
+ const ended = { issue, taken_at, ended_at: now.toISOString() };
29
+ if (is_fullrun === true) ended.is_fullrun = true;
30
+ stamp_file.replace_stamp(target, [...read_ended(target), ended].slice(-KEPT_RUNS));
31
+ }
32
+ var run_hold_ended = { KEPT_RUNS, ended_path, read_ended, record_ended };
33
+
34
+ export {
35
+ run_hold_ended
36
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  lane_session_broker
3
- } from "./chunk-4MGTNY2L.js";
3
+ } from "./chunk-ZI3SABMH.js";
4
4
  import {
5
5
  ts_entry_loader
6
6
  } from "./chunk-VHRNXWVP.js";
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-SD4EX75H.js";
18
18
  import {
19
19
  test_e2e_stamp
20
- } from "./chunk-VHLDQ3PH.js";
20
+ } from "./chunk-HHS3LYLV.js";
21
21
  import {
22
22
  git_gh_command
23
23
  } from "./chunk-NRULNBYI.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  lane_session_broker
3
- } from "./chunk-4MGTNY2L.js";
3
+ } from "./chunk-ZI3SABMH.js";
4
4
  import {
5
5
  run_ship_review
6
- } from "./chunk-KD3SEAMV.js";
6
+ } from "./chunk-7HYYHCTN.js";
7
7
  import {
8
8
  review_attest
9
9
  } from "./chunk-URZ4RDC4.js";