git-stack-cli 2.5.3 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/js/index.js CHANGED
@@ -31944,7 +31944,7 @@ var React18 = __toESM(require_react(), 1);
31944
31944
  var React10 = __toESM(require_react(), 1);
31945
31945
 
31946
31946
  // src/core/colors.ts
31947
- var colors = {
31947
+ var colors = Object.freeze({
31948
31948
  red: "rgb(248, 81, 73)",
31949
31949
  green: "rgb(63, 185, 80)",
31950
31950
  purple: "rgb(163, 113, 247)",
@@ -31952,8 +31952,9 @@ var colors = {
31952
31952
  orange: "rgb(255, 166, 87)",
31953
31953
  yellow: "rgb(234, 179, 8)",
31954
31954
  gray: "rgb(110, 118, 129)",
31955
- lightGray: "rgb(125, 133, 144)"
31956
- };
31955
+ lightGray: "rgb(125, 133, 144)",
31956
+ white: "whiteBright"
31957
+ });
31957
31958
 
31958
31959
  // src/app/Brackets.tsx
31959
31960
  function Brackets(props) {
@@ -32061,6 +32062,11 @@ function YesNoPrompt(props) {
32061
32062
  }, choices))));
32062
32063
  }
32063
32064
 
32065
+ // src/core/assertNever.ts
32066
+ function assertNever(value) {
32067
+ console.error("[assertNever]", { value });
32068
+ }
32069
+
32064
32070
  // src/core/cli.ts
32065
32071
  import * as child from "node:child_process";
32066
32072
 
@@ -37053,6 +37059,7 @@ var BaseStore = createStore()(immer2((set2, get) => ({
37053
37059
  master_branch: "origin/master",
37054
37060
  head: null,
37055
37061
  branch_name: null,
37062
+ merge_base: null,
37056
37063
  commit_range: null,
37057
37064
  commit_map: null,
37058
37065
  pr_templates: [],
@@ -37279,6 +37286,7 @@ async function cli(unsafe_command, unsafe_options) {
37279
37286
  function write_output(value) {
37280
37287
  output += value;
37281
37288
  state.actions.debug(value, id);
37289
+ options.onOutput?.(value);
37282
37290
  }
37283
37291
  childProcess.stdout?.on("data", (data) => {
37284
37292
  const value = String(data);
@@ -37442,25 +37450,34 @@ function AutoUpdate(props) {
37442
37450
  }
37443
37451
  }
37444
37452
  React18.useEffect(() => {
37445
- let status2 = "done";
37453
+ switch (state.status) {
37454
+ case "init":
37455
+ case "prompt":
37456
+ case "install":
37457
+ break;
37458
+ case "done": {
37459
+ props.onDone?.();
37460
+ break;
37461
+ }
37462
+ default:
37463
+ assertNever(state.status);
37464
+ }
37465
+ }, [state.status]);
37466
+ React18.useEffect(() => {
37467
+ let status2 = "init";
37446
37468
  let latest_version = null;
37447
37469
  let is_brew_bun_standalone = false;
37448
- const local_version = "2.5.3";
37470
+ const local_version = "2.6.1";
37449
37471
  const is_output = props_ref.current.verbose || props_ref.current.force;
37450
37472
  async function auto_update() {
37451
37473
  if (!local_version) {
37452
37474
  throw new Error("Auto update requires process.env.CLI_VERSION to be set");
37453
37475
  }
37454
- if (is_output) {
37455
- handle_output(/* @__PURE__ */ React18.createElement(Text, {
37456
- key: "init"
37457
- }, "Checking for latest version..."));
37458
- }
37459
37476
  const timeout_ms = is_finite_value(props.timeoutMs) ? props.timeoutMs : 2 * 1000;
37460
37477
  const npm_json = await Promise.race([
37461
37478
  fetch_json(`https://registry.npmjs.org/${props.name}`),
37462
37479
  sleep(timeout_ms).then(() => {
37463
- throw new Error("Timeout");
37480
+ throw new Error("AutoUpdate timeout");
37464
37481
  })
37465
37482
  ]);
37466
37483
  latest_version = npm_json?.["dist-tags"]?.latest;
@@ -37497,32 +37514,37 @@ function AutoUpdate(props) {
37497
37514
  }));
37498
37515
  }
37499
37516
  const semver_result = semver_compare(latest_version, local_version);
37517
+ if (props_ref.current.verbose) {
37518
+ handle_output(/* @__PURE__ */ React18.createElement(Text, {
37519
+ dimColor: true
37520
+ }, JSON.stringify({ semver_result })));
37521
+ }
37500
37522
  if (semver_result === 0) {
37523
+ status2 = "done";
37501
37524
  if (is_output) {
37502
37525
  handle_output(/* @__PURE__ */ React18.createElement(Text, null, "✅ Everything up to date. ", /* @__PURE__ */ React18.createElement(Brackets, null, latest_version)));
37503
37526
  }
37504
37527
  return;
37505
37528
  }
37506
- if (semver_result === -1) {
37507
- throw new Error(`latest version < local_version, skipping auto update [${latest_version} < ${local_version}]`);
37529
+ if (semver_result === 1) {
37530
+ status2 = "prompt";
37508
37531
  }
37509
- status2 = "prompt";
37532
+ throw new Error("AutoUpdate failed");
37510
37533
  }
37511
37534
  const onError = props_ref.current.onError || (() => {
37512
37535
  });
37513
37536
  auto_update().then(() => {
37514
37537
  patch({ status: status2, local_version, latest_version, is_brew_bun_standalone });
37515
37538
  }).catch((error) => {
37516
- patch({ status: status2, error, local_version, latest_version, is_brew_bun_standalone });
37517
- onError(error);
37518
37539
  if (props_ref.current.verbose) {
37519
37540
  handle_output(/* @__PURE__ */ React18.createElement(Text, {
37520
37541
  key: "error",
37521
37542
  color: colors.red
37522
37543
  }, error?.message));
37523
37544
  }
37524
- }).finally(() => {
37525
- props.onDone?.();
37545
+ status2 = "done";
37546
+ patch({ status: status2, error, local_version, latest_version, is_brew_bun_standalone });
37547
+ onError(error);
37526
37548
  });
37527
37549
  }, []);
37528
37550
  const status = function render_status() {
@@ -37532,47 +37554,45 @@ function AutoUpdate(props) {
37532
37554
  case "prompt": {
37533
37555
  let install_command = "";
37534
37556
  if (state.is_brew_bun_standalone) {
37535
- install_command = `npm install -g ${props.name}@latest`;
37557
+ install_command = "brew install magus/git-stack/git-stack";
37536
37558
  } else {
37537
- install_command = "brew upgrade magus/git-stack/git-stack";
37559
+ install_command = `npm install -g ${props.name}@latest`;
37538
37560
  }
37539
37561
  return /* @__PURE__ */ React18.createElement(YesNoPrompt, {
37540
37562
  message: /* @__PURE__ */ React18.createElement(Box_default, {
37541
37563
  flexDirection: "column"
37564
+ }, /* @__PURE__ */ React18.createElement(Box_default, {
37565
+ flexDirection: "column"
37542
37566
  }, /* @__PURE__ */ React18.createElement(Text, {
37543
37567
  color: colors.yellow
37544
37568
  }, /* @__PURE__ */ React18.createElement(FormatText, {
37545
37569
  wrapper: /* @__PURE__ */ React18.createElement(Text, null),
37546
- message: "New version available {latest_version}, would you like to update?",
37570
+ message: "New version available {latest_version}",
37547
37571
  values: {
37548
37572
  latest_version: /* @__PURE__ */ React18.createElement(Brackets, null, state.latest_version)
37549
37573
  }
37550
- }), ","), /* @__PURE__ */ React18.createElement(Text, null, " "), /* @__PURE__ */ React18.createElement(Command, null, install_command), /* @__PURE__ */ React18.createElement(Text, null, " "), /* @__PURE__ */ React18.createElement(FormatText, {
37574
+ }), ","), /* @__PURE__ */ React18.createElement(Text, null, " "), /* @__PURE__ */ React18.createElement(Command, null, install_command), /* @__PURE__ */ React18.createElement(Text, null, " ")), /* @__PURE__ */ React18.createElement(Box_default, null, /* @__PURE__ */ React18.createElement(FormatText, {
37551
37575
  wrapper: /* @__PURE__ */ React18.createElement(Text, {
37552
37576
  color: colors.yellow
37553
37577
  }),
37554
37578
  message: "Would you like to run the above command to update?"
37555
- })),
37579
+ }))),
37556
37580
  onYes: async () => {
37557
- handle_output(/* @__PURE__ */ React18.createElement(FormatText, {
37558
- key: "install",
37559
- wrapper: /* @__PURE__ */ React18.createElement(Text, null),
37560
- message: "Installing {name}@{version}...",
37561
- values: {
37562
- name: /* @__PURE__ */ React18.createElement(Text, {
37563
- color: colors.yellow
37564
- }, props.name),
37565
- version: /* @__PURE__ */ React18.createElement(Text, {
37566
- color: colors.blue
37567
- }, state.latest_version)
37568
- }
37569
- }));
37581
+ handle_output(/* @__PURE__ */ React18.createElement(Command, null, install_command));
37570
37582
  patch({ status: "install" });
37571
- await cli(install_command);
37572
- patch({ status: "exit" });
37583
+ await cli(install_command, {
37584
+ env: {
37585
+ ...process.env,
37586
+ HOMEBREW_COLOR: "1"
37587
+ },
37588
+ onOutput: (data) => {
37589
+ handle_output(/* @__PURE__ */ React18.createElement(Text, null, data));
37590
+ }
37591
+ });
37573
37592
  handle_output(/* @__PURE__ */ React18.createElement(Text, {
37574
37593
  key: "done"
37575
- }, "Auto update done."));
37594
+ }, " Installed ", /* @__PURE__ */ React18.createElement(Brackets, null, state.latest_version)));
37595
+ patch({ status: "done" });
37576
37596
  },
37577
37597
  onNo: () => {
37578
37598
  patch({ status: "done" });
@@ -37581,8 +37601,6 @@ function AutoUpdate(props) {
37581
37601
  }
37582
37602
  case "install":
37583
37603
  return null;
37584
- case "exit":
37585
- return null;
37586
37604
  case "done":
37587
37605
  return props.children;
37588
37606
  }
@@ -38409,15 +38427,19 @@ function GitReviseTodo(args) {
38409
38427
  GitReviseTodo.todo = function todo(args) {
38410
38428
  const entry_list = [];
38411
38429
  for (const commit2 of args.commit_list) {
38412
- const id = commit2.branch_id;
38413
- const title = commit2.title;
38414
- invariant(id, "commit.branch_id must exist");
38415
- invariant(title, "commit.title must exist");
38416
- const metadata = { id, title };
38417
- const unsafe_message_with_id = write(commit2.full_message, metadata);
38418
- let message_with_id = unsafe_message_with_id;
38419
38430
  const sha = commit2.sha.slice(0, 12);
38420
- const entry_lines = [`++ pick ${sha}`, message_with_id];
38431
+ const entry_lines = [`++ pick ${sha}`];
38432
+ const id = commit2.branch_id;
38433
+ if (id == null || id === UNASSIGNED) {
38434
+ entry_lines.push(commit2.full_message);
38435
+ } else {
38436
+ const title = commit2.title;
38437
+ invariant(title, "commit.title must exist");
38438
+ const metadata = { id, title };
38439
+ const unsafe_message_with_id = write(commit2.full_message, metadata);
38440
+ const message_with_id = unsafe_message_with_id;
38441
+ entry_lines.push(message_with_id);
38442
+ }
38421
38443
  const entry = entry_lines.join(`
38422
38444
  `);
38423
38445
  entry_list.push(entry);
@@ -38761,27 +38783,9 @@ async function run() {
38761
38783
  }
38762
38784
  }
38763
38785
  actions.debug(`master_branch = ${master_branch}`);
38764
- const branch_name = (await cli("git rev-parse --abbrev-ref HEAD")).stdout;
38765
- if (branch_name === "HEAD") {
38766
- actions.error("Must run within a branch.");
38767
- actions.exit(0);
38768
- return;
38769
- }
38770
- if (`origin/${branch_name}` === master_branch) {
38771
- actions.error("Must run within a branch.");
38772
- actions.exit(0);
38773
- return;
38774
- }
38775
38786
  const head = (await cli("git rev-parse HEAD")).stdout;
38787
+ const branch_name = (await cli("git rev-parse --abbrev-ref HEAD")).stdout;
38776
38788
  const merge_base = (await cli(`git merge-base HEAD ${master_branch}`)).stdout;
38777
- if (head === merge_base) {
38778
- actions.newline();
38779
- actions.output(/* @__PURE__ */ React27.createElement(Text, {
38780
- color: colors.gray
38781
- }, "No changes detected."));
38782
- actions.exit(0);
38783
- return;
38784
- }
38785
38789
  const origin_url = (await cli(`git config --get remote.origin.url`)).stdout;
38786
38790
  const repo_path = match_group(origin_url, RE5.repo_path, "repo_path");
38787
38791
  const repo_root = (await cli(`git rev-parse --show-toplevel`)).stdout;
@@ -38791,6 +38795,7 @@ async function run() {
38791
38795
  state.master_branch = master_branch;
38792
38796
  state.head = head;
38793
38797
  state.branch_name = branch_name;
38798
+ state.merge_base = merge_base;
38794
38799
  });
38795
38800
  } catch (err) {
38796
38801
  actions.error("Unable to gather git metadata.");
@@ -38927,7 +38932,7 @@ async function run3() {
38927
38932
  }
38928
38933
 
38929
38934
  // src/app/Main.tsx
38930
- var React45 = __toESM(require_react(), 1);
38935
+ var React44 = __toESM(require_react(), 1);
38931
38936
 
38932
38937
  // src/app/LocalMergeRebase.tsx
38933
38938
  var React35 = __toESM(require_react(), 1);
@@ -39013,11 +39018,6 @@ function Container(props) {
39013
39018
  }));
39014
39019
  }
39015
39020
 
39016
- // src/core/assertNever.ts
39017
- function assertNever(value) {
39018
- console.error("[assertNever]", { value });
39019
- }
39020
-
39021
39021
  // src/app/StatusTable.tsx
39022
39022
  function StatusTable() {
39023
39023
  const commit_range = Store.useState((state) => state.commit_range);
@@ -39165,11 +39165,7 @@ async function run4() {
39165
39165
  Store.setState((state2) => {
39166
39166
  state2.step = "pre-local-merge-rebase";
39167
39167
  });
39168
- } else if (needs_update) {
39169
- Store.setState((state2) => {
39170
- state2.step = "pre-select-commit-ranges";
39171
- });
39172
- } else if (argv.force) {
39168
+ } else if (needs_update || argv.force) {
39173
39169
  Store.setState((state2) => {
39174
39170
  state2.step = "select-commit-ranges";
39175
39171
  });
@@ -39228,7 +39224,7 @@ function Rebase(props) {
39228
39224
  return /* @__PURE__ */ React34.createElement(Await, {
39229
39225
  fallback: /* @__PURE__ */ React34.createElement(Text, {
39230
39226
  color: colors.yellow
39231
- }, "Rebasing commits…"),
39227
+ }, "Rebasing…"),
39232
39228
  function: () => Rebase.run(props)
39233
39229
  });
39234
39230
  }
@@ -39250,12 +39246,50 @@ Rebase.run = async function run5(props) {
39250
39246
  handle_exit2();
39251
39247
  return 19;
39252
39248
  });
39249
+ const master_branch_name = master_branch.replace(/^origin\//, "");
39253
39250
  const temp_branch_name = `${branch_name}_${short_id()}`;
39254
39251
  try {
39255
39252
  process.chdir(repo_root);
39256
39253
  await cli(`pwd`);
39257
- const master_branch_name = master_branch.replace(/^origin\//, "");
39258
39254
  await cli(`git fetch --no-tags -v origin ${master_branch_name}`);
39255
+ if (branch_name === master_branch_name) {
39256
+ await rebase_master();
39257
+ } else {
39258
+ await rebase_branch();
39259
+ }
39260
+ actions.unregister_abort_handler();
39261
+ } catch (err) {
39262
+ actions.error("Unable to rebase.");
39263
+ if (err instanceof Error) {
39264
+ actions.error(err.message);
39265
+ }
39266
+ actions.exit(20);
39267
+ }
39268
+ const next_commit_range = await range();
39269
+ actions.output(/* @__PURE__ */ React34.createElement(FormatText, {
39270
+ wrapper: /* @__PURE__ */ React34.createElement(Text, {
39271
+ color: colors.green
39272
+ }),
39273
+ message: "✅ {branch_name} in sync with {origin_branch}",
39274
+ values: {
39275
+ branch_name: /* @__PURE__ */ React34.createElement(Brackets, null, branch_name),
39276
+ origin_branch: /* @__PURE__ */ React34.createElement(Brackets, null, master_branch)
39277
+ }
39278
+ }));
39279
+ actions.set((state2) => {
39280
+ state2.commit_range = next_commit_range;
39281
+ });
39282
+ if (props.onComplete) {
39283
+ props.onComplete();
39284
+ } else {
39285
+ actions.output(/* @__PURE__ */ React34.createElement(Status, null));
39286
+ actions.exit(0);
39287
+ }
39288
+ async function rebase_master() {
39289
+ await cli(`git switch -C "${master_branch_name}" "${master_branch}"`);
39290
+ }
39291
+ async function rebase_branch() {
39292
+ invariant(commit_range, "commit_range must exist");
39259
39293
  const master_sha = (await cli(`git rev-parse ${master_branch}`)).stdout;
39260
39294
  const rebase_merge_base = master_sha;
39261
39295
  await cli(`git checkout -b ${temp_branch_name} ${rebase_merge_base}`);
@@ -39302,33 +39336,6 @@ Rebase.run = async function run5(props) {
39302
39336
  }
39303
39337
  await cli(`git branch -f ${branch_name} ${temp_branch_name}`);
39304
39338
  restore_git();
39305
- actions.unregister_abort_handler();
39306
- } catch (err) {
39307
- actions.error("Unable to rebase.");
39308
- if (err instanceof Error) {
39309
- actions.error(err.message);
39310
- }
39311
- actions.exit(20);
39312
- }
39313
- const next_commit_range = await range();
39314
- actions.output(/* @__PURE__ */ React34.createElement(FormatText, {
39315
- wrapper: /* @__PURE__ */ React34.createElement(Text, {
39316
- color: colors.green
39317
- }),
39318
- message: "✅ {branch_name} in sync with {origin_branch}",
39319
- values: {
39320
- branch_name: /* @__PURE__ */ React34.createElement(Brackets, null, branch_name),
39321
- origin_branch: /* @__PURE__ */ React34.createElement(Brackets, null, master_branch)
39322
- }
39323
- }));
39324
- actions.set((state2) => {
39325
- state2.commit_range = next_commit_range;
39326
- });
39327
- if (props.onComplete) {
39328
- props.onComplete();
39329
- } else {
39330
- actions.output(/* @__PURE__ */ React34.createElement(Status, null));
39331
- actions.exit(0);
39332
39339
  }
39333
39340
  function restore_git() {
39334
39341
  const spawn_options = { ignoreExitCode: true };
@@ -39594,34 +39601,11 @@ var PR_TEMPLATE = Object.freeze({
39594
39601
  });
39595
39602
  var PR_TEMPLATE_KEY_LIST = Object.keys(PR_TEMPLATE);
39596
39603
 
39597
- // src/app/PreSelectCommitRanges.tsx
39598
- var React40 = __toESM(require_react(), 1);
39599
- function PreSelectCommitRanges() {
39600
- const actions = Store.useActions();
39601
- const argv = Store.useState((state) => state.argv);
39602
- React40.useEffect(() => {
39603
- if (argv.force) {
39604
- Store.setState((state) => {
39605
- state.step = "select-commit-ranges";
39606
- });
39607
- }
39608
- }, [argv]);
39609
- return /* @__PURE__ */ React40.createElement(YesNoPrompt, {
39610
- message: "Some commits are new or outdated, would you like to select new commit ranges?",
39611
- onYes: () => {
39612
- actions.set((state) => {
39613
- state.step = "select-commit-ranges";
39614
- });
39615
- },
39616
- onNo: () => actions.exit(0)
39617
- });
39618
- }
39619
-
39620
39604
  // src/app/SelectCommitRanges.tsx
39621
- var React43 = __toESM(require_react(), 1);
39605
+ var React42 = __toESM(require_react(), 1);
39622
39606
 
39623
39607
  // src/app/MultiSelect.tsx
39624
- var React41 = __toESM(require_react(), 1);
39608
+ var React40 = __toESM(require_react(), 1);
39625
39609
 
39626
39610
  // src/core/clamp.ts
39627
39611
  function clamp(value, min, max) {
@@ -39644,7 +39628,7 @@ function wrap_index(value, list) {
39644
39628
 
39645
39629
  // src/app/MultiSelect.tsx
39646
39630
  function MultiSelect(props) {
39647
- const [selected_set, select] = React41.useReducer((state, value) => {
39631
+ const [selected_set, select] = React40.useReducer((state, value) => {
39648
39632
  const next = new Set(state);
39649
39633
  if (next.has(value)) {
39650
39634
  next.delete(value);
@@ -39660,27 +39644,28 @@ function MultiSelect(props) {
39660
39644
  });
39661
39645
  return set2;
39662
39646
  });
39663
- const [index, set_index] = React41.useReducer((_, value) => {
39647
+ const [index, set_index] = React40.useReducer((_, value) => {
39664
39648
  const next_index = clamp(value, 0, props.items.length - 1);
39665
39649
  return next_index;
39666
39650
  }, 0, function find_initial_index() {
39667
39651
  let last_enabled;
39668
39652
  for (let i2 = props.items.length - 1;i2 >= 0; i2--) {
39669
39653
  const item = props.items[i2];
39670
- if (!item.disabled) {
39671
- last_enabled = i2;
39654
+ if (item.disabled) {
39655
+ continue;
39672
39656
  }
39673
- if (!item.selected && !item.disabled) {
39657
+ last_enabled = i2;
39658
+ if (!item.selected) {
39674
39659
  return i2;
39675
39660
  }
39676
39661
  }
39677
39662
  if (is_finite_value(last_enabled)) {
39678
39663
  return last_enabled;
39679
39664
  }
39680
- return 0;
39665
+ return props.startIndex || 0;
39681
39666
  });
39682
- const selectRef = React41.useRef(false);
39683
- React41.useEffect(() => {
39667
+ const selectRef = React40.useRef(false);
39668
+ React40.useEffect(() => {
39684
39669
  if (!selectRef.current) {
39685
39670
  return;
39686
39671
  }
@@ -39690,7 +39675,7 @@ function MultiSelect(props) {
39690
39675
  const state = selected_list.map((index2) => props.items[index2].value);
39691
39676
  props.onSelect({ item, selected, state });
39692
39677
  }, [selected_set]);
39693
- React41.useEffect(() => {
39678
+ React40.useEffect(() => {
39694
39679
  const item = props.items[index].value;
39695
39680
  const selected_list = Array.from(selected_set);
39696
39681
  const selected = selected_set.has(index);
@@ -39732,13 +39717,13 @@ function MultiSelect(props) {
39732
39717
  }
39733
39718
  }
39734
39719
  });
39735
- return /* @__PURE__ */ React41.createElement(Box_default, {
39720
+ return /* @__PURE__ */ React40.createElement(Box_default, {
39736
39721
  flexDirection: "column"
39737
39722
  }, props.items.map((item, i2) => {
39738
39723
  const active = i2 === index;
39739
39724
  const selected = selected_set.has(i2);
39740
39725
  const disabled = item.disabled || false;
39741
- return /* @__PURE__ */ React41.createElement(ItemRow, {
39726
+ return /* @__PURE__ */ React40.createElement(ItemRow, {
39742
39727
  key: i2,
39743
39728
  label: item.label,
39744
39729
  active,
@@ -39750,32 +39735,26 @@ function MultiSelect(props) {
39750
39735
  }
39751
39736
  function ItemRow(props) {
39752
39737
  let color;
39753
- let bold;
39754
39738
  let underline;
39755
39739
  let dimColor;
39756
39740
  if (props.active) {
39757
39741
  color = colors.blue;
39758
39742
  underline = true;
39759
39743
  }
39760
- if (props.selected) {
39761
- bold = true;
39762
- }
39763
39744
  if (props.disabled) {
39764
39745
  color = "";
39765
- bold = false;
39766
39746
  underline = false;
39767
39747
  dimColor = true;
39768
39748
  }
39769
- return /* @__PURE__ */ React41.createElement(Box_default, {
39749
+ return /* @__PURE__ */ React40.createElement(Box_default, {
39770
39750
  flexDirection: "row",
39771
39751
  gap: 1
39772
- }, /* @__PURE__ */ React41.createElement(Radio, {
39752
+ }, /* @__PURE__ */ React40.createElement(Radio, {
39773
39753
  selected: props.selected,
39774
39754
  disabled: props.disabled
39775
- }), /* @__PURE__ */ React41.createElement(Box_default, {
39755
+ }), /* @__PURE__ */ React40.createElement(Box_default, {
39776
39756
  width: props.maxWidth
39777
- }, /* @__PURE__ */ React41.createElement(Text, {
39778
- bold,
39757
+ }, /* @__PURE__ */ React40.createElement(Text, {
39779
39758
  underline,
39780
39759
  color,
39781
39760
  dimColor,
@@ -39797,7 +39776,7 @@ function Radio(props) {
39797
39776
  color = colors.gray;
39798
39777
  dimColor = true;
39799
39778
  }
39800
- return /* @__PURE__ */ React41.createElement(Text, {
39779
+ return /* @__PURE__ */ React40.createElement(Text, {
39801
39780
  bold: props.selected,
39802
39781
  color,
39803
39782
  dimColor
@@ -39805,14 +39784,14 @@ function Radio(props) {
39805
39784
  }
39806
39785
 
39807
39786
  // src/app/TextInput.tsx
39808
- var React42 = __toESM(require_react(), 1);
39787
+ var React41 = __toESM(require_react(), 1);
39809
39788
  function TextInput(props) {
39810
- const [value, set_value] = React42.useState(get_value(props));
39811
- React42.useEffect(function sync_value_prop() {
39789
+ const [value, set_value] = React41.useState(get_value(props));
39790
+ React41.useEffect(function sync_value_prop() {
39812
39791
  set_value(get_value(props));
39813
39792
  }, [props.value]);
39814
- const [caret_visible, set_caret_visible] = React42.useState(false);
39815
- React42.useEffect(function blink_caret() {
39793
+ const [caret_visible, set_caret_visible] = React41.useState(false);
39794
+ React41.useEffect(function blink_caret() {
39816
39795
  const interval_ms = 500;
39817
39796
  let timeoutId = setTimeout(tick, interval_ms);
39818
39797
  function tick() {
@@ -39825,7 +39804,13 @@ function TextInput(props) {
39825
39804
  }, []);
39826
39805
  use_input_default((input, key) => {
39827
39806
  let next_value = value;
39828
- if (key.backspace || key.delete) {
39807
+ if (key.escape) {
39808
+ if (value === "") {
39809
+ props.onCancel?.();
39810
+ } else {
39811
+ next_value = "";
39812
+ }
39813
+ } else if (key.backspace || key.delete) {
39829
39814
  next_value = value.slice(0, -1);
39830
39815
  } else if (key.return) {
39831
39816
  props.onSubmit?.(next_value);
@@ -39844,12 +39829,12 @@ function TextInput(props) {
39844
39829
  set_value(next_value);
39845
39830
  props.onChange?.(next_value);
39846
39831
  });
39847
- return /* @__PURE__ */ React42.createElement(Box_default, {
39832
+ return /* @__PURE__ */ React41.createElement(Box_default, {
39848
39833
  borderStyle: "single",
39849
39834
  minHeight: 1,
39850
39835
  borderColor: colors.yellow,
39851
39836
  borderDimColor: true
39852
- }, /* @__PURE__ */ React42.createElement(Text, null, value || ""), /* @__PURE__ */ React42.createElement(Text, {
39837
+ }, /* @__PURE__ */ React41.createElement(Text, null, value || ""), /* @__PURE__ */ React41.createElement(Text, {
39853
39838
  color: colors.yellow,
39854
39839
  dimColor: true,
39855
39840
  inverse: caret_visible
@@ -39868,26 +39853,26 @@ function gs_short_id() {
39868
39853
  function SelectCommitRanges() {
39869
39854
  const commit_range = Store.useState((state) => state.commit_range);
39870
39855
  invariant(commit_range, "commit_range must exist");
39871
- return /* @__PURE__ */ React43.createElement(SelectCommitRangesInternal, {
39856
+ return /* @__PURE__ */ React42.createElement(SelectCommitRangesInternal, {
39872
39857
  commit_range
39873
39858
  });
39874
39859
  }
39875
39860
  function SelectCommitRangesInternal(props) {
39876
39861
  const actions = Store.useActions();
39877
39862
  const argv = Store.useState((state) => state.argv);
39878
- const [selected_group_id, set_selected_group_id] = React43.useState(() => {
39863
+ const [selected_group_id, set_selected_group_id] = React42.useState(() => {
39879
39864
  const first_group = props.commit_range.group_list.find((g2) => g2.id !== props.commit_range.UNASSIGNED);
39880
39865
  if (first_group) {
39881
39866
  return first_group.id;
39882
39867
  }
39883
39868
  return props.commit_range.UNASSIGNED;
39884
39869
  });
39885
- const [group_input, set_group_input] = React43.useState(false);
39886
- const [new_group_list, create_group] = React43.useReducer((group_list2, group2) => {
39870
+ const [group_input, set_group_input] = React42.useState(false);
39871
+ const [new_group_list, create_group] = React42.useReducer((group_list2, group2) => {
39887
39872
  const next_group_list = group_list2.concat(group2);
39888
39873
  return next_group_list;
39889
39874
  }, []);
39890
- const [commit_map, update_commit_map] = React43.useReducer((map, args) => {
39875
+ const [commit_map, update_commit_map] = React42.useReducer((map, args) => {
39891
39876
  map.set(args.key, args.value);
39892
39877
  return new Map(map);
39893
39878
  }, new Map, (map) => {
@@ -39898,9 +39883,12 @@ function SelectCommitRangesInternal(props) {
39898
39883
  });
39899
39884
  const group_list = [];
39900
39885
  let unassigned_count = 0;
39886
+ let assigned_count = 0;
39901
39887
  for (const [, group_id] of commit_map.entries()) {
39902
39888
  if (group_id === null) {
39903
39889
  unassigned_count++;
39890
+ } else {
39891
+ assigned_count++;
39904
39892
  }
39905
39893
  }
39906
39894
  const total_group_count = new_group_list.length + props.commit_range.group_list.length;
@@ -39928,29 +39916,37 @@ function SelectCommitRangesInternal(props) {
39928
39916
  if (current_index === -1) {
39929
39917
  current_index = 0;
39930
39918
  }
39919
+ const has_unassigned_commits = unassigned_count > 0;
39920
+ const has_assigned_commits = assigned_count > 0;
39921
+ const sync_status = detect_sync_status();
39931
39922
  use_input_default((input, key) => {
39932
- const inputLower = input.toLowerCase();
39933
- const hasUnassignedCommits = unassigned_count > 0;
39934
- if (!hasUnassignedCommits && inputLower === "s") {
39923
+ const input_lower = input.toLowerCase();
39924
+ if (input_lower === SYMBOL.s) {
39925
+ if (group_input) {
39926
+ return;
39927
+ }
39928
+ if (sync_status === "disabled") {
39929
+ return;
39930
+ }
39935
39931
  actions.set((state) => {
39936
- state.commit_map = {};
39937
- for (const [sha, id] of commit_map.entries()) {
39938
- if (id) {
39939
- const group2 = group_list.find((g2) => g2.id === id);
39940
- if (group2) {
39941
- state.commit_map[sha] = group2;
39942
- }
39932
+ const state_commit_map = {};
39933
+ for (let [sha, id] of commit_map.entries()) {
39934
+ if (!id) {
39935
+ id = props.commit_range.UNASSIGNED;
39936
+ const title = "allow_unassigned";
39937
+ state_commit_map[sha] = { id, title };
39938
+ continue;
39943
39939
  }
39940
+ const group2 = group_list.find((g2) => g2.id === id);
39941
+ invariant(group2, "group must exist");
39942
+ state_commit_map[sha] = group2;
39944
39943
  }
39945
- switch (inputLower) {
39946
- case "s":
39947
- state.step = "pre-manual-rebase";
39948
- break;
39949
- }
39944
+ state.commit_map = state_commit_map;
39945
+ state.step = "pre-manual-rebase";
39950
39946
  });
39951
39947
  return;
39952
39948
  }
39953
- if (hasUnassignedCommits && inputLower === "c") {
39949
+ if (has_unassigned_commits && input_lower === SYMBOL.c) {
39954
39950
  set_group_input(true);
39955
39951
  return;
39956
39952
  }
@@ -39968,12 +39964,17 @@ function SelectCommitRangesInternal(props) {
39968
39964
  const group = group_list[current_index];
39969
39965
  const multiselect_disabled = group_input;
39970
39966
  const multiselect_disableSelect = group.id === props.commit_range.UNASSIGNED;
39967
+ const max_width = 80;
39968
+ const [focused, set_focused] = React42.useState("");
39969
+ const has_groups = group.id !== props.commit_range.UNASSIGNED;
39971
39970
  const items = props.commit_range.commit_list.map((commit2) => {
39972
39971
  const commit_metadata_id = commit_map.get(commit2.sha);
39973
39972
  const selected = commit_metadata_id !== null;
39974
39973
  let disabled;
39975
39974
  if (group_input) {
39976
39975
  disabled = true;
39976
+ } else if (!has_groups) {
39977
+ disabled = true;
39977
39978
  } else {
39978
39979
  disabled = Boolean(selected && commit_metadata_id !== group.id);
39979
39980
  }
@@ -39985,24 +39986,84 @@ function SelectCommitRangesInternal(props) {
39985
39986
  };
39986
39987
  });
39987
39988
  items.reverse();
39988
- const left_arrow = `${SYMBOL.left} `;
39989
- const right_arrow = ` ${SYMBOL.right}`;
39990
- const group_position = `(${current_index + 1}/${group_list.length}) `;
39991
- const max_group_label_width = 80;
39992
- let group_title_width = max_group_label_width;
39993
- group_title_width -= group_position.length;
39994
- group_title_width -= left_arrow.length + right_arrow.length;
39995
- group_title_width = Math.min(group.title.length, group_title_width);
39996
- let max_item_width = max_group_label_width;
39997
- max_item_width -= left_arrow.length + right_arrow.length;
39998
- const [focused, set_focused] = React43.useState("");
39999
- return /* @__PURE__ */ React43.createElement(Box_default, {
39989
+ return /* @__PURE__ */ React42.createElement(Box_default, {
40000
39990
  flexDirection: "column"
40001
- }, /* @__PURE__ */ React43.createElement(Box_default, {
39991
+ }, /* @__PURE__ */ React42.createElement(Box_default, {
39992
+ height: 1
39993
+ }), has_groups || group_input ? null : /* @__PURE__ */ React42.createElement(Box_default, {
39994
+ flexDirection: "column"
39995
+ }, /* @__PURE__ */ React42.createElement(Text, {
39996
+ bold: true,
39997
+ color: colors.blue
39998
+ }, "\uD83D\uDC4B Welcome to ", /* @__PURE__ */ React42.createElement(Command, null, "git stack"), "!"), /* @__PURE__ */ React42.createElement(Text, {
39999
+ color: colors.blue
40000
+ }, /* @__PURE__ */ React42.createElement(FormatText, {
40001
+ message: "Press {c} to {create} a new PR",
40002
+ values: {
40003
+ c: /* @__PURE__ */ React42.createElement(Text, {
40004
+ bold: true,
40005
+ color: colors.green
40006
+ }, "c"),
40007
+ create: /* @__PURE__ */ React42.createElement(Text, {
40008
+ bold: true,
40009
+ color: colors.green
40010
+ }, /* @__PURE__ */ React42.createElement(Parens, null, "c"), "reate")
40011
+ }
40012
+ }))), !has_groups || group_input ? null : /* @__PURE__ */ React42.createElement(React42.Fragment, null, /* @__PURE__ */ React42.createElement(Box_default, {
40013
+ width: max_width,
40014
+ flexDirection: "row"
40015
+ }, /* @__PURE__ */ React42.createElement(Box_default, {
40016
+ flexDirection: "row"
40017
+ }, /* @__PURE__ */ React42.createElement(Text, {
40018
+ bold: true,
40019
+ color: colors.green
40020
+ }, SYMBOL.left), /* @__PURE__ */ React42.createElement(Box_default, {
40021
+ width: 1
40022
+ }), /* @__PURE__ */ React42.createElement(Text, {
40023
+ color: colors.gray
40024
+ }, "Pull request"), /* @__PURE__ */ React42.createElement(Box_default, {
40025
+ width: 1
40026
+ }), /* @__PURE__ */ React42.createElement(Text, {
40027
+ color: colors.gray
40028
+ }, `(${current_index + 1}/${group_list.length})`), /* @__PURE__ */ React42.createElement(Box_default, {
40029
+ width: 1
40030
+ }), /* @__PURE__ */ React42.createElement(Text, {
40031
+ bold: true,
40032
+ color: colors.green
40033
+ }, SYMBOL.right))), /* @__PURE__ */ React42.createElement(Box_default, {
40034
+ width: max_width
40035
+ }, /* @__PURE__ */ React42.createElement(Text, {
40036
+ wrap: "truncate-end",
40037
+ bold: true,
40038
+ color: colors.white
40039
+ }, group.title))), !group_input ? null : /* @__PURE__ */ React42.createElement(React42.Fragment, null, /* @__PURE__ */ React42.createElement(Box_default, {
40002
40040
  height: 1
40003
- }), /* @__PURE__ */ React43.createElement(MultiSelect, {
40041
+ }), /* @__PURE__ */ React42.createElement(FormatText, {
40042
+ wrapper: /* @__PURE__ */ React42.createElement(Text, {
40043
+ color: colors.gray
40044
+ }),
40045
+ message: "Enter a title for the PR {note}",
40046
+ values: {
40047
+ note: /* @__PURE__ */ React42.createElement(Parens, null, /* @__PURE__ */ React42.createElement(FormatText, {
40048
+ message: "press {enter} to submit",
40049
+ values: {
40050
+ enter: /* @__PURE__ */ React42.createElement(Text, {
40051
+ bold: true,
40052
+ color: colors.green
40053
+ }, SYMBOL.enter)
40054
+ }
40055
+ }))
40056
+ }
40057
+ }), /* @__PURE__ */ React42.createElement(TextInput, {
40058
+ defaultValue: focused,
40059
+ onSubmit: submit_group_input,
40060
+ onCancel: () => set_group_input(false)
40061
+ })), /* @__PURE__ */ React42.createElement(Box_default, {
40062
+ height: 1
40063
+ }), /* @__PURE__ */ React42.createElement(MultiSelect, {
40064
+ startIndex: items.length - 1,
40004
40065
  items,
40005
- maxWidth: max_item_width,
40066
+ maxWidth: max_width,
40006
40067
  disabled: multiselect_disabled,
40007
40068
  disableSelect: multiselect_disableSelect,
40008
40069
  onFocus: (args) => {
@@ -40018,108 +40079,76 @@ function SelectCommitRangesInternal(props) {
40018
40079
  }
40019
40080
  update_commit_map({ key, value });
40020
40081
  }
40021
- }), /* @__PURE__ */ React43.createElement(Box_default, {
40082
+ }), /* @__PURE__ */ React42.createElement(Box_default, {
40022
40083
  height: 1
40023
- }), /* @__PURE__ */ React43.createElement(Box_default, {
40024
- width: max_group_label_width,
40025
- flexDirection: "row"
40026
- }, /* @__PURE__ */ React43.createElement(Text, null, left_arrow), /* @__PURE__ */ React43.createElement(Text, null, group_position), /* @__PURE__ */ React43.createElement(Box_default, {
40027
- width: group_title_width,
40028
- justifyContent: "center"
40029
- }, /* @__PURE__ */ React43.createElement(Text, {
40030
- wrap: "truncate-end"
40031
- }, group.title)), /* @__PURE__ */ React43.createElement(Text, null, right_arrow)), /* @__PURE__ */ React43.createElement(Box_default, {
40032
- height: 1
40033
- }), unassigned_count > 0 ? /* @__PURE__ */ React43.createElement(FormatText, {
40034
- wrapper: /* @__PURE__ */ React43.createElement(Text, {
40084
+ }), has_unassigned_commits ? /* @__PURE__ */ React42.createElement(React42.Fragment, null, /* @__PURE__ */ React42.createElement(FormatText, {
40085
+ wrapper: /* @__PURE__ */ React42.createElement(Text, {
40035
40086
  color: colors.gray
40036
40087
  }),
40037
- message: "{count} unassigned commits, press {c} to {create} a new group",
40088
+ message: "{count} unassigned commits",
40038
40089
  values: {
40039
- count: /* @__PURE__ */ React43.createElement(Text, {
40090
+ count: /* @__PURE__ */ React42.createElement(Text, {
40040
40091
  color: colors.yellow,
40041
40092
  bold: true
40042
- }, unassigned_count),
40043
- c: /* @__PURE__ */ React43.createElement(Text, {
40044
- bold: true,
40045
- color: colors.green
40046
- }, "c"),
40047
- create: /* @__PURE__ */ React43.createElement(Text, {
40048
- bold: true,
40049
- color: colors.green
40050
- }, /* @__PURE__ */ React43.createElement(Parens, null, "c"), "reate")
40051
- }
40052
- }) : /* @__PURE__ */ React43.createElement(React43.Fragment, null, argv.sync ? /* @__PURE__ */ React43.createElement(FormatText, {
40053
- wrapper: /* @__PURE__ */ React43.createElement(Text, null),
40054
- message: "\uD83C\uDF89 Done! Press {s} to {sync} the commits to Github",
40055
- values: {
40056
- s: /* @__PURE__ */ React43.createElement(Text, {
40057
- bold: true,
40058
- color: colors.green
40059
- }, "s"),
40060
- sync: /* @__PURE__ */ React43.createElement(Text, {
40061
- bold: true,
40062
- color: colors.green
40063
- }, /* @__PURE__ */ React43.createElement(Parens, null, "s"), "ync")
40093
+ }, unassigned_count)
40064
40094
  }
40065
- }) : /* @__PURE__ */ React43.createElement(FormatText, {
40066
- wrapper: /* @__PURE__ */ React43.createElement(Text, null),
40067
- message: "\uD83C\uDF89 Done! Press {s} to {save} the commits locally",
40095
+ }), group_input ? null : /* @__PURE__ */ React42.createElement(FormatText, {
40096
+ wrapper: /* @__PURE__ */ React42.createElement(Text, {
40097
+ color: colors.gray
40098
+ }),
40099
+ message: "Press {c} to {create} a new PR",
40068
40100
  values: {
40069
- s: /* @__PURE__ */ React43.createElement(Text, {
40101
+ c: /* @__PURE__ */ React42.createElement(Text, {
40070
40102
  bold: true,
40071
40103
  color: colors.green
40072
- }, "s"),
40073
- save: /* @__PURE__ */ React43.createElement(Text, {
40104
+ }, "c"),
40105
+ create: /* @__PURE__ */ React42.createElement(Text, {
40074
40106
  bold: true,
40075
40107
  color: colors.green
40076
- }, /* @__PURE__ */ React43.createElement(Parens, null, "s"), "save")
40108
+ }, /* @__PURE__ */ React42.createElement(Parens, null, "c"), "reate")
40077
40109
  }
40078
- })), !group_input ? null : /* @__PURE__ */ React43.createElement(React43.Fragment, null, /* @__PURE__ */ React43.createElement(Box_default, {
40079
- height: 1
40080
- }), /* @__PURE__ */ React43.createElement(FormatText, {
40081
- wrapper: /* @__PURE__ */ React43.createElement(Text, {
40110
+ }), sync_status !== "allow_unassigned" ? null : /* @__PURE__ */ React42.createElement(FormatText, {
40111
+ wrapper: /* @__PURE__ */ React42.createElement(Text, {
40082
40112
  color: colors.gray
40083
40113
  }),
40084
- message: "Enter a title for the PR {note}",
40114
+ message: "Press {s} to {sync} the {count} assigned commits to Github",
40085
40115
  values: {
40086
- note: /* @__PURE__ */ React43.createElement(Parens, null, /* @__PURE__ */ React43.createElement(FormatText, {
40087
- message: "press {enter} to submit",
40088
- values: {
40089
- enter: /* @__PURE__ */ React43.createElement(Text, {
40090
- bold: true,
40091
- color: colors.green
40092
- }, SYMBOL.enter)
40093
- }
40094
- }))
40116
+ ...S_TO_SYNC_VALUES,
40117
+ count: /* @__PURE__ */ React42.createElement(Text, {
40118
+ color: colors.yellow,
40119
+ bold: true
40120
+ }, assigned_count)
40095
40121
  }
40096
- }), /* @__PURE__ */ React43.createElement(TextInput, {
40097
- defaultValue: focused,
40098
- onSubmit: submit_group_input
40099
- }), /* @__PURE__ */ React43.createElement(Box_default, {
40100
- height: 1
40101
- })), /* @__PURE__ */ React43.createElement(Box_default, null, /* @__PURE__ */ React43.createElement(FormatText, {
40102
- wrapper: /* @__PURE__ */ React43.createElement(Text, {
40122
+ })) : /* @__PURE__ */ React42.createElement(React42.Fragment, null, argv.sync ? /* @__PURE__ */ React42.createElement(FormatText, {
40123
+ wrapper: /* @__PURE__ */ React42.createElement(Text, null),
40124
+ message: "\uD83C\uDF89 Done! Press {s} to {sync} the commits to Github",
40125
+ values: S_TO_SYNC_VALUES
40126
+ }) : /* @__PURE__ */ React42.createElement(FormatText, {
40127
+ wrapper: /* @__PURE__ */ React42.createElement(Text, null),
40128
+ message: "\uD83C\uDF89 Done! Press {s} to {save} the commits locally",
40129
+ values: S_TO_SYNC_VALUES
40130
+ })), /* @__PURE__ */ React42.createElement(Box_default, null, /* @__PURE__ */ React42.createElement(FormatText, {
40131
+ wrapper: /* @__PURE__ */ React42.createElement(Text, {
40103
40132
  color: colors.gray
40104
40133
  }),
40105
- message: "Press {left} and {right} to view PR groups",
40134
+ message: "Press {left} and {right} to view PRs",
40106
40135
  values: {
40107
- left: /* @__PURE__ */ React43.createElement(Text, {
40136
+ left: /* @__PURE__ */ React42.createElement(Text, {
40108
40137
  bold: true,
40109
40138
  color: colors.green
40110
40139
  }, SYMBOL.left),
40111
- right: /* @__PURE__ */ React43.createElement(Text, {
40140
+ right: /* @__PURE__ */ React42.createElement(Text, {
40112
40141
  bold: true,
40113
40142
  color: colors.green
40114
40143
  }, SYMBOL.right)
40115
40144
  }
40116
- })), /* @__PURE__ */ React43.createElement(Box_default, null, /* @__PURE__ */ React43.createElement(FormatText, {
40117
- wrapper: /* @__PURE__ */ React43.createElement(Text, {
40145
+ })), /* @__PURE__ */ React42.createElement(Box_default, null, /* @__PURE__ */ React42.createElement(FormatText, {
40146
+ wrapper: /* @__PURE__ */ React42.createElement(Text, {
40118
40147
  color: colors.gray
40119
40148
  }),
40120
40149
  message: "Press {enter} to toggle commit selection",
40121
40150
  values: {
40122
- enter: /* @__PURE__ */ React43.createElement(Text, {
40151
+ enter: /* @__PURE__ */ React42.createElement(Text, {
40123
40152
  bold: true,
40124
40153
  color: colors.green
40125
40154
  }, SYMBOL.enter)
@@ -40136,29 +40165,67 @@ function SelectCommitRangesInternal(props) {
40136
40165
  }
40137
40166
  function submit_group_input(title) {
40138
40167
  const id = get_group_id();
40139
- actions.output(/* @__PURE__ */ React43.createElement(FormatText, {
40140
- wrapper: /* @__PURE__ */ React43.createElement(Text, {
40168
+ actions.output(/* @__PURE__ */ React42.createElement(FormatText, {
40169
+ wrapper: /* @__PURE__ */ React42.createElement(Text, {
40141
40170
  dimColor: true
40142
40171
  }),
40143
- message: "Created new group {group} {note}",
40172
+ message: "Created new PR {group} {note}",
40144
40173
  values: {
40145
- group: /* @__PURE__ */ React43.createElement(Brackets, null, title),
40146
- note: /* @__PURE__ */ React43.createElement(Parens, null, id)
40174
+ group: /* @__PURE__ */ React42.createElement(Brackets, null, title),
40175
+ note: /* @__PURE__ */ React42.createElement(Parens, null, id)
40147
40176
  }
40148
40177
  }));
40149
40178
  create_group({ id, title });
40150
40179
  set_selected_group_id(id);
40151
40180
  set_group_input(false);
40152
40181
  }
40182
+ function detect_sync_status() {
40183
+ if (!has_unassigned_commits) {
40184
+ return "allow";
40185
+ }
40186
+ if (!has_assigned_commits) {
40187
+ return "disabled";
40188
+ }
40189
+ let allow_unassigned_sync = null;
40190
+ for (let i2 = 0;i2 < props.commit_range.commit_list.length; i2++) {
40191
+ const commit2 = props.commit_range.commit_list[i2];
40192
+ const group_id = commit_map.get(commit2.sha);
40193
+ if (allow_unassigned_sync === null) {
40194
+ if (group_id === null) {
40195
+ allow_unassigned_sync = true;
40196
+ }
40197
+ } else {
40198
+ if (group_id) {
40199
+ allow_unassigned_sync = false;
40200
+ }
40201
+ }
40202
+ }
40203
+ if (allow_unassigned_sync) {
40204
+ return "allow_unassigned";
40205
+ }
40206
+ return "disabled";
40207
+ }
40153
40208
  }
40154
40209
  var SYMBOL = {
40155
40210
  left: "←",
40156
40211
  right: "→",
40157
- enter: "Enter"
40212
+ enter: "Enter",
40213
+ c: "c",
40214
+ s: "s"
40215
+ };
40216
+ var S_TO_SYNC_VALUES = {
40217
+ s: /* @__PURE__ */ React42.createElement(Text, {
40218
+ bold: true,
40219
+ color: colors.green
40220
+ }, "s"),
40221
+ sync: /* @__PURE__ */ React42.createElement(Text, {
40222
+ bold: true,
40223
+ color: colors.green
40224
+ }, /* @__PURE__ */ React42.createElement(Parens, null, "s"), "ync")
40158
40225
  };
40159
40226
 
40160
40227
  // src/app/SyncGithub.tsx
40161
- var React44 = __toESM(require_react(), 1);
40228
+ var React43 = __toESM(require_react(), 1);
40162
40229
  var import_last = __toESM(require_last(), 1);
40163
40230
 
40164
40231
  // src/core/StackSummaryTable.ts
@@ -40263,8 +40330,8 @@ var RE6 = {
40263
40330
 
40264
40331
  // src/app/SyncGithub.tsx
40265
40332
  function SyncGithub() {
40266
- return /* @__PURE__ */ React44.createElement(Await, {
40267
- fallback: /* @__PURE__ */ React44.createElement(Text, {
40333
+ return /* @__PURE__ */ React43.createElement(Await, {
40334
+ fallback: /* @__PURE__ */ React43.createElement(Text, {
40268
40335
  color: colors.yellow
40269
40336
  }, "Syncing…"),
40270
40337
  function: run9
@@ -40307,15 +40374,15 @@ async function run9() {
40307
40374
  git_push_command.push(target);
40308
40375
  }
40309
40376
  await cli(git_push_command);
40310
- const pr_url_list = commit_range.group_list.map(get_group_url);
40377
+ const pr_url_list = push_group_list.map(get_group_url);
40311
40378
  const after_push_tasks = [];
40312
40379
  for (const group of push_group_list) {
40313
40380
  after_push_tasks.push(after_push({ group, pr_url_list }));
40314
40381
  }
40315
40382
  await Promise.all(after_push_tasks);
40316
40383
  const update_pr_body_tasks = [];
40317
- for (let i2 = 0;i2 < commit_range.group_list.length; i2++) {
40318
- const group = commit_range.group_list[i2];
40384
+ for (let i2 = 0;i2 < push_group_list.length; i2++) {
40385
+ const group = push_group_list[i2];
40319
40386
  const selected_url = pr_url_list[i2];
40320
40387
  const task = update_pr_body({ group, selected_url, pr_url_list });
40321
40388
  update_pr_body_tasks.push(task);
@@ -40343,7 +40410,9 @@ async function run9() {
40343
40410
  break;
40344
40411
  }
40345
40412
  const group = commit_range.group_list[index];
40346
- push_group_list2.unshift(group);
40413
+ if (group.id !== commit_range.UNASSIGNED) {
40414
+ push_group_list2.unshift(group);
40415
+ }
40347
40416
  }
40348
40417
  return push_group_list2;
40349
40418
  }
@@ -40420,25 +40489,23 @@ function Main() {
40420
40489
  case "loading":
40421
40490
  return null;
40422
40491
  case "github-api-error":
40423
- return /* @__PURE__ */ React45.createElement(GithubApiError, null);
40492
+ return /* @__PURE__ */ React44.createElement(GithubApiError, null);
40424
40493
  case "status":
40425
- return /* @__PURE__ */ React45.createElement(Status, null);
40494
+ return /* @__PURE__ */ React44.createElement(Status, null);
40426
40495
  case "local-merge-rebase":
40427
- return /* @__PURE__ */ React45.createElement(LocalMergeRebase, null);
40496
+ return /* @__PURE__ */ React44.createElement(LocalMergeRebase, null);
40428
40497
  case "pre-local-merge-rebase":
40429
- return /* @__PURE__ */ React45.createElement(PreLocalMergeRebase, null);
40430
- case "pre-select-commit-ranges":
40431
- return /* @__PURE__ */ React45.createElement(PreSelectCommitRanges, null);
40498
+ return /* @__PURE__ */ React44.createElement(PreLocalMergeRebase, null);
40432
40499
  case "select-commit-ranges":
40433
- return /* @__PURE__ */ React45.createElement(SelectCommitRanges, null);
40500
+ return /* @__PURE__ */ React44.createElement(SelectCommitRanges, null);
40434
40501
  case "pre-manual-rebase":
40435
- return /* @__PURE__ */ React45.createElement(PreManualRebase, null);
40502
+ return /* @__PURE__ */ React44.createElement(PreManualRebase, null);
40436
40503
  case "manual-rebase":
40437
- return /* @__PURE__ */ React45.createElement(ManualRebase, null);
40504
+ return /* @__PURE__ */ React44.createElement(ManualRebase, null);
40438
40505
  case "sync-github":
40439
- return /* @__PURE__ */ React45.createElement(SyncGithub, null);
40506
+ return /* @__PURE__ */ React44.createElement(SyncGithub, null);
40440
40507
  case "post-rebase-status":
40441
- return /* @__PURE__ */ React45.createElement(PostRebaseStatus, null);
40508
+ return /* @__PURE__ */ React44.createElement(PostRebaseStatus, null);
40442
40509
  default:
40443
40510
  assertNever(step);
40444
40511
  return null;
@@ -40446,56 +40513,56 @@ function Main() {
40446
40513
  }
40447
40514
 
40448
40515
  // src/app/Output.tsx
40449
- var React46 = __toESM(require_react(), 1);
40516
+ var React45 = __toESM(require_react(), 1);
40450
40517
  function Output2() {
40451
40518
  const output = Store.useState((state) => state.output);
40452
40519
  const pending_output = Store.useState((state) => state.pending_output);
40453
40520
  const pending_output_items = Object.values(pending_output);
40454
- return /* @__PURE__ */ React46.createElement(React46.Fragment, null, /* @__PURE__ */ React46.createElement(Static, {
40521
+ return /* @__PURE__ */ React45.createElement(React45.Fragment, null, /* @__PURE__ */ React45.createElement(Static, {
40455
40522
  items: output
40456
40523
  }, (node, i2) => {
40457
- return /* @__PURE__ */ React46.createElement(Box_default, {
40524
+ return /* @__PURE__ */ React45.createElement(Box_default, {
40458
40525
  key: i2
40459
40526
  }, node);
40460
40527
  }), pending_output_items.map((node_list, i2) => {
40461
- return /* @__PURE__ */ React46.createElement(Box_default, {
40528
+ return /* @__PURE__ */ React45.createElement(Box_default, {
40462
40529
  key: i2
40463
- }, /* @__PURE__ */ React46.createElement(Text, null, node_list.map((text, j) => {
40464
- return /* @__PURE__ */ React46.createElement(React46.Fragment, {
40530
+ }, /* @__PURE__ */ React45.createElement(Text, null, node_list.map((text, j) => {
40531
+ return /* @__PURE__ */ React45.createElement(React45.Fragment, {
40465
40532
  key: j
40466
- }, /* @__PURE__ */ React46.createElement(Text, null, text));
40533
+ }, /* @__PURE__ */ React45.createElement(Text, null, text));
40467
40534
  })));
40468
40535
  }));
40469
40536
  }
40470
40537
 
40471
40538
  // src/app/Providers.tsx
40472
- var React47 = __toESM(require_react(), 1);
40539
+ var React46 = __toESM(require_react(), 1);
40473
40540
  var import_react_intl2 = __toESM(require_react_intl(), 1);
40474
40541
  function Providers(props) {
40475
- return /* @__PURE__ */ React47.createElement(import_react_intl2.IntlProvider, {
40542
+ return /* @__PURE__ */ React46.createElement(import_react_intl2.IntlProvider, {
40476
40543
  locale: "en"
40477
40544
  }, props.children);
40478
40545
  }
40479
40546
 
40480
40547
  // src/app/RebaseCheck.tsx
40481
- var React48 = __toESM(require_react(), 1);
40548
+ var React47 = __toESM(require_react(), 1);
40482
40549
  import path8 from "node:path";
40483
40550
  function reducer5(state, patch) {
40484
40551
  return { ...state, ...patch };
40485
40552
  }
40486
40553
  function RebaseCheck(props) {
40487
40554
  const actions = Store.useActions();
40488
- const [state, patch] = React48.useReducer(reducer5, {
40555
+ const [state, patch] = React47.useReducer(reducer5, {
40489
40556
  status: "init"
40490
40557
  });
40491
40558
  switch (state.status) {
40492
40559
  case "done":
40493
40560
  return props.children;
40494
40561
  case "prompt":
40495
- return /* @__PURE__ */ React48.createElement(YesNoPrompt, {
40496
- message: /* @__PURE__ */ React48.createElement(Text, {
40562
+ return /* @__PURE__ */ React47.createElement(YesNoPrompt, {
40563
+ message: /* @__PURE__ */ React47.createElement(Text, {
40497
40564
  color: colors.yellow
40498
- }, /* @__PURE__ */ React48.createElement(Command, null, "git rebase"), " detected, would you like to abort it?"),
40565
+ }, /* @__PURE__ */ React47.createElement(Command, null, "git rebase"), " detected, would you like to abort it?"),
40499
40566
  onYes: async () => {
40500
40567
  await cli(`git rebase --abort`);
40501
40568
  patch({ status: "done" });
@@ -40505,11 +40572,11 @@ function RebaseCheck(props) {
40505
40572
  }
40506
40573
  });
40507
40574
  default:
40508
- return /* @__PURE__ */ React48.createElement(Await, {
40575
+ return /* @__PURE__ */ React47.createElement(Await, {
40509
40576
  function: run10,
40510
- fallback: /* @__PURE__ */ React48.createElement(Text, {
40577
+ fallback: /* @__PURE__ */ React47.createElement(Text, {
40511
40578
  color: colors.yellow
40512
- }, "Checking for ", /* @__PURE__ */ React48.createElement(Command, null, "git rebase"), "…")
40579
+ }, "Checking for ", /* @__PURE__ */ React47.createElement(Command, null, "git rebase"), "…")
40513
40580
  });
40514
40581
  }
40515
40582
  async function run10() {
@@ -40530,6 +40597,55 @@ function RebaseCheck(props) {
40530
40597
  }
40531
40598
  }
40532
40599
 
40600
+ // src/app/RequireBranch.tsx
40601
+ var React48 = __toESM(require_react(), 1);
40602
+ function RequireBranch(props) {
40603
+ const fallback = /* @__PURE__ */ React48.createElement(Text, {
40604
+ color: colors.yellow
40605
+ }, "Gathering local git information…");
40606
+ return /* @__PURE__ */ React48.createElement(Await, {
40607
+ fallback,
40608
+ function: run10
40609
+ }, props.children);
40610
+ }
40611
+ async function run10() {
40612
+ const state = Store.getState();
40613
+ const actions = Store.getState().actions;
40614
+ const master_branch = state.master_branch;
40615
+ const head = state.head;
40616
+ const branch_name = state.branch_name;
40617
+ const merge_base = state.merge_base;
40618
+ invariant(head, "head must exist");
40619
+ invariant(branch_name, "branch_name must exist");
40620
+ invariant(merge_base, "merge_base must exist");
40621
+ try {
40622
+ if (branch_name === "HEAD") {
40623
+ actions.error("Must run within a branch.");
40624
+ actions.exit(0);
40625
+ return;
40626
+ }
40627
+ if (`origin/${branch_name}` === master_branch) {
40628
+ actions.error("Must run within a branch.");
40629
+ actions.exit(0);
40630
+ return;
40631
+ }
40632
+ if (head === merge_base) {
40633
+ actions.newline();
40634
+ actions.output(/* @__PURE__ */ React48.createElement(Text, {
40635
+ color: colors.gray
40636
+ }, "No changes detected."));
40637
+ actions.exit(0);
40638
+ return;
40639
+ }
40640
+ } catch (err) {
40641
+ actions.error("Unable to detect branch changes.");
40642
+ if (err instanceof Error) {
40643
+ actions.error(err.message);
40644
+ }
40645
+ actions.exit(17);
40646
+ }
40647
+ }
40648
+
40533
40649
  // src/app/VerboseDebugInfo.tsx
40534
40650
  var React49 = __toESM(require_react(), 1);
40535
40651
  function VerboseDebugInfo(props) {
@@ -40538,10 +40654,10 @@ function VerboseDebugInfo(props) {
40538
40654
  }, "Logging verbose debug information…");
40539
40655
  return /* @__PURE__ */ React49.createElement(Await, {
40540
40656
  fallback,
40541
- function: run10
40657
+ function: run11
40542
40658
  }, props.children);
40543
40659
  }
40544
- async function run10() {
40660
+ async function run11() {
40545
40661
  const actions = Store.getState().actions;
40546
40662
  try {
40547
40663
  await cli(`echo HOME=$HOME`);
@@ -40563,10 +40679,10 @@ var React50 = __toESM(require_react(), 1);
40563
40679
  function Fixup() {
40564
40680
  return /* @__PURE__ */ React50.createElement(Await, {
40565
40681
  fallback: null,
40566
- function: run11
40682
+ function: run12
40567
40683
  });
40568
40684
  }
40569
- async function run11() {
40685
+ async function run12() {
40570
40686
  const state = Store.getState();
40571
40687
  const actions = state.actions;
40572
40688
  const argv = state.argv;
@@ -40651,10 +40767,10 @@ function Log() {
40651
40767
  const available_width = stdout.columns || 80;
40652
40768
  return /* @__PURE__ */ React51.createElement(Await, {
40653
40769
  fallback: null,
40654
- function: () => run12({ available_width })
40770
+ function: () => run13({ available_width })
40655
40771
  });
40656
40772
  }
40657
- async function run12(args) {
40773
+ async function run13(args) {
40658
40774
  const state = Store.getState();
40659
40775
  const actions = state.actions;
40660
40776
  const process_argv = state.process_argv;
@@ -40685,10 +40801,10 @@ var React52 = __toESM(require_react(), 1);
40685
40801
  function Update() {
40686
40802
  return /* @__PURE__ */ React52.createElement(Await, {
40687
40803
  fallback: null,
40688
- function: run13
40804
+ function: run14
40689
40805
  });
40690
40806
  }
40691
- async function run13() {
40807
+ async function run14() {
40692
40808
  const state = Store.getState();
40693
40809
  const actions = state.actions;
40694
40810
  actions.exit(0);
@@ -40810,7 +40926,7 @@ function MaybeMain() {
40810
40926
  } else if (positional_list.has("rebase")) {
40811
40927
  return /* @__PURE__ */ React55.createElement(DependencyCheck, null, /* @__PURE__ */ React55.createElement(DirtyCheck, null, /* @__PURE__ */ React55.createElement(GatherMetadata, null, /* @__PURE__ */ React55.createElement(LocalCommitStatus, null, /* @__PURE__ */ React55.createElement(Rebase, null)))));
40812
40928
  }
40813
- return /* @__PURE__ */ React55.createElement(React55.Fragment, null, !argv.verbose ? null : /* @__PURE__ */ React55.createElement(GithubApiError, null), /* @__PURE__ */ React55.createElement(DependencyCheck, null, /* @__PURE__ */ React55.createElement(DirtyCheck, null, /* @__PURE__ */ React55.createElement(GatherMetadata, null, /* @__PURE__ */ React55.createElement(LocalCommitStatus, null, /* @__PURE__ */ React55.createElement(DetectInitialPR, null, /* @__PURE__ */ React55.createElement(Main, null)))))));
40929
+ return /* @__PURE__ */ React55.createElement(React55.Fragment, null, !argv.verbose ? null : /* @__PURE__ */ React55.createElement(GithubApiError, null), /* @__PURE__ */ React55.createElement(DependencyCheck, null, /* @__PURE__ */ React55.createElement(DirtyCheck, null, /* @__PURE__ */ React55.createElement(GatherMetadata, null, /* @__PURE__ */ React55.createElement(RequireBranch, null, /* @__PURE__ */ React55.createElement(LocalCommitStatus, null, /* @__PURE__ */ React55.createElement(DetectInitialPR, null, /* @__PURE__ */ React55.createElement(Main, null))))))));
40814
40930
  }
40815
40931
 
40816
40932
  // node_modules/.pnpm/yargs@17.7.2/node_modules/yargs/lib/platform-shims/esm.mjs
@@ -45675,7 +45791,7 @@ var yargs_default = Yargs;
45675
45791
 
45676
45792
  // src/command.ts
45677
45793
  async function command2() {
45678
- return yargs_default(hideBin(process.argv)).scriptName("git stack").usage("Usage: git stack [command] [options]").command("$0", "Sync commit ranges to Github", (yargs) => yargs.options(DefaultOptions)).command("fixup [commit]", "Amend staged changes to a specific commit in history", (yargs) => yargs.positional("commit", FixupOptions.commit)).command("log [args...]", "Print an abbreviated log with numbered commits, useful for git stack fixup", (yargs) => yargs.strict(false)).command("rebase", "Update local branch via rebase with latest changes from origin master branch", (yargs) => yargs).command(["update", "upgrade"], "Check and install the latest version of git stack", (yargs) => yargs).option("verbose", GlobalOptions.verbose).wrap(123).strict().version("2.5.3").showHidden("show-hidden", "Show hidden options via `git stack help --show-hidden`").help("help", "Show usage via `git stack help`").argv;
45794
+ return yargs_default(hideBin(process.argv)).scriptName("git stack").usage("Usage: git stack [command] [options]").command("$0", "Sync commit ranges to Github", (yargs) => yargs.options(DefaultOptions)).command("fixup [commit]", "Amend staged changes to a specific commit in history", (yargs) => yargs.positional("commit", FixupOptions.commit)).command("log [args...]", "Print an abbreviated log with numbered commits, useful for git stack fixup", (yargs) => yargs.strict(false)).command("rebase", "Update local branch via rebase with latest changes from origin master branch", (yargs) => yargs).command(["update", "upgrade"], "Check and install the latest version of git stack", (yargs) => yargs).option("verbose", GlobalOptions.verbose).wrap(123).strict().version("2.6.1").showHidden("show-hidden", "Show hidden options via `git stack help --show-hidden`").help("help", "Show usage via `git stack help`").argv;
45679
45795
  }
45680
45796
  var GlobalOptions = {
45681
45797
  verbose: {