@ondrej-svec/hog 1.6.0 → 1.6.2

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/cli.js CHANGED
@@ -1243,7 +1243,6 @@ function useActions({
1243
1243
  } else {
1244
1244
  t.resolve(`#${issue.number} \u2192 ${optionName}`);
1245
1245
  }
1246
- refresh();
1247
1246
  }).catch((err) => {
1248
1247
  t.reject(`Status change failed: ${err instanceof Error ? err.message : String(err)}`);
1249
1248
  refresh();
@@ -1483,8 +1482,8 @@ ${dueLine}` : dueLine;
1483
1482
  t.resolve(`Moved ${total} issue${total > 1 ? "s" : ""} to ${optionName}`);
1484
1483
  } else {
1485
1484
  t.reject(`${ok} moved to ${optionName}, ${failed.length} failed`);
1485
+ refresh();
1486
1486
  }
1487
- refresh();
1488
1487
  return failed;
1489
1488
  },
1490
1489
  [toast, refresh, mutateData]
@@ -1958,6 +1957,31 @@ function findFallback(items, oldSection) {
1958
1957
  }
1959
1958
  return items.find((i) => i.type === "header") ?? items[0];
1960
1959
  }
1960
+ function relocateOnToggle(state, section) {
1961
+ if (!state.selectedId) return { selectedId: null, selectedSection: null };
1962
+ const selected = state.allItems.find((i) => i.id === state.selectedId);
1963
+ if (!selected) return { selectedId: state.selectedId, selectedSection: state.selectedSection };
1964
+ const insideCollapsedSubSection = selected.subSection === section;
1965
+ const insideCollapsedSection = !insideCollapsedSubSection && selected.section === section && selected.type !== "header";
1966
+ if (insideCollapsedSubSection) {
1967
+ const subHeader = state.allItems.find((i) => i.id === section && i.type === "subHeader");
1968
+ if (subHeader) return { selectedId: subHeader.id, selectedSection: subHeader.section };
1969
+ } else if (insideCollapsedSection) {
1970
+ const header = state.allItems.find((i) => i.section === section && i.type === "header");
1971
+ if (header) return { selectedId: header.id, selectedSection: header.section };
1972
+ }
1973
+ return { selectedId: state.selectedId, selectedSection: state.selectedSection };
1974
+ }
1975
+ function relocateOnCollapseAll(state) {
1976
+ if (!state.selectedId) return { selectedId: null, selectedSection: null };
1977
+ const selected = state.allItems.find((i) => i.id === state.selectedId);
1978
+ if (!selected || selected.type === "header") {
1979
+ return { selectedId: state.selectedId, selectedSection: state.selectedSection };
1980
+ }
1981
+ const header = state.allItems.find((i) => i.section === selected.section && i.type === "header");
1982
+ if (header) return { selectedId: header.id, selectedSection: header.section };
1983
+ return { selectedId: state.selectedId, selectedSection: state.selectedSection };
1984
+ }
1961
1985
  function navReducer(state, action) {
1962
1986
  switch (action.type) {
1963
1987
  case "SET_ITEMS": {
@@ -1974,7 +1998,8 @@ function navReducer(state, action) {
1974
1998
  ...state,
1975
1999
  selectedSection: selected?.section ?? state.selectedSection,
1976
2000
  sections,
1977
- collapsedSections
2001
+ collapsedSections,
2002
+ allItems: action.items
1978
2003
  };
1979
2004
  }
1980
2005
  const fallback = findFallback(action.items, state.selectedSection);
@@ -1982,7 +2007,8 @@ function navReducer(state, action) {
1982
2007
  selectedId: fallback?.id ?? null,
1983
2008
  selectedSection: fallback?.section ?? null,
1984
2009
  sections,
1985
- collapsedSections
2010
+ collapsedSections,
2011
+ allItems: action.items
1986
2012
  };
1987
2013
  }
1988
2014
  case "SELECT": {
@@ -1994,15 +2020,19 @@ function navReducer(state, action) {
1994
2020
  }
1995
2021
  case "TOGGLE_SECTION": {
1996
2022
  const next = new Set(state.collapsedSections);
1997
- if (next.has(action.section)) {
1998
- next.delete(action.section);
1999
- } else {
2023
+ const isCollapsing = !next.has(action.section);
2024
+ if (isCollapsing) {
2000
2025
  next.add(action.section);
2026
+ const cursor = relocateOnToggle(state, action.section);
2027
+ return { ...state, collapsedSections: next, ...cursor };
2001
2028
  }
2029
+ next.delete(action.section);
2002
2030
  return { ...state, collapsedSections: next };
2003
2031
  }
2004
2032
  case "COLLAPSE_ALL": {
2005
- return { ...state, collapsedSections: new Set(state.sections) };
2033
+ const next = new Set(state.sections);
2034
+ const cursor = relocateOnCollapseAll(state);
2035
+ return { ...state, collapsedSections: next, ...cursor };
2006
2036
  }
2007
2037
  default:
2008
2038
  return state;
@@ -2022,7 +2052,8 @@ function useNavigation(allItems) {
2022
2052
  selectedId: null,
2023
2053
  selectedSection: null,
2024
2054
  sections: [],
2025
- collapsedSections: /* @__PURE__ */ new Set()
2055
+ collapsedSections: /* @__PURE__ */ new Set(),
2056
+ allItems: []
2026
2057
  });
2027
2058
  const prevItemsRef = useRef4(null);
2028
2059
  if (allItems !== prevItemsRef.current) {
@@ -2069,6 +2100,7 @@ function useNavigation(allItems) {
2069
2100
  const toggleSection = useCallback5(() => {
2070
2101
  const currentItem = visibleItems[selectedIndex];
2071
2102
  if (!currentItem) return;
2103
+ if (currentItem.type === "item") return;
2072
2104
  const key = currentItem.type === "subHeader" ? currentItem.id : currentItem.section;
2073
2105
  dispatch({ type: "TOGGLE_SECTION", section: key });
2074
2106
  }, [selectedIndex, visibleItems]);
@@ -2232,6 +2264,11 @@ var init_use_toast = __esm({
2232
2264
 
2233
2265
  // src/board/hooks/use-ui-state.ts
2234
2266
  import { useCallback as useCallback7, useReducer as useReducer2 } from "react";
2267
+ function enterStatusMode(state) {
2268
+ if (state.mode !== "normal" && state.mode !== "overlay:bulkAction") return state;
2269
+ const previousMode = state.mode === "overlay:bulkAction" ? "multiSelect" : "normal";
2270
+ return { ...state, mode: "overlay:status", previousMode };
2271
+ }
2235
2272
  function uiReducer(state, action) {
2236
2273
  switch (action.type) {
2237
2274
  case "ENTER_SEARCH":
@@ -2241,12 +2278,7 @@ function uiReducer(state, action) {
2241
2278
  if (state.mode !== "normal") return state;
2242
2279
  return { ...state, mode: "overlay:comment", previousMode: "normal" };
2243
2280
  case "ENTER_STATUS":
2244
- if (state.mode !== "normal" && state.mode !== "overlay:bulkAction") return state;
2245
- return {
2246
- ...state,
2247
- mode: "overlay:status",
2248
- previousMode: state.mode === "overlay:bulkAction" ? "multiSelect" : "normal"
2249
- };
2281
+ return enterStatusMode(state);
2250
2282
  case "ENTER_CREATE":
2251
2283
  if (state.mode !== "normal") return state;
2252
2284
  return { ...state, mode: "overlay:create", previousMode: "normal" };
@@ -2566,16 +2598,16 @@ var init_bulk_action_menu = __esm({
2566
2598
 
2567
2599
  // src/board/ink-instance.ts
2568
2600
  function setInkInstance(instance) {
2569
- _instance = instance;
2601
+ inkInstance = instance;
2570
2602
  }
2571
2603
  function getInkInstance() {
2572
- return _instance;
2604
+ return inkInstance;
2573
2605
  }
2574
- var _instance;
2606
+ var inkInstance;
2575
2607
  var init_ink_instance = __esm({
2576
2608
  "src/board/ink-instance.ts"() {
2577
2609
  "use strict";
2578
- _instance = null;
2610
+ inkInstance = null;
2579
2611
  }
2580
2612
  });
2581
2613
 
@@ -2631,8 +2663,8 @@ function CommentInput({
2631
2663
  tmpDir = mkdtempSync(join3(tmpdir(), "hog-comment-"));
2632
2664
  tmpFile = join3(tmpDir, "comment.md");
2633
2665
  writeFileSync3(tmpFile, value);
2634
- const inkInstance = getInkInstance();
2635
- inkInstance?.clear();
2666
+ const inkInstance2 = getInkInstance();
2667
+ inkInstance2?.clear();
2636
2668
  setRawMode(false);
2637
2669
  spawnSync(cmd, [...extraArgs, tmpFile], { stdio: "inherit" });
2638
2670
  const content = readFileSync3(tmpFile, "utf-8").trim();
@@ -2644,7 +2676,7 @@ function CommentInput({
2644
2676
  }
2645
2677
  } finally {
2646
2678
  onResumeRef.current?.();
2647
- if (tmpFile) {
2679
+ if (tmpDir) {
2648
2680
  try {
2649
2681
  rmSync(tmpDir, { recursive: true, force: true });
2650
2682
  } catch {
@@ -3203,8 +3235,8 @@ function NlCreateOverlay({
3203
3235
  tmpDir = mkdtempSync2(join4(tmpdir2(), "hog-body-"));
3204
3236
  tmpFile = join4(tmpDir, "body.md");
3205
3237
  writeFileSync4(tmpFile, body);
3206
- const inkInstance = getInkInstance();
3207
- inkInstance?.clear();
3238
+ const inkInstance2 = getInkInstance();
3239
+ inkInstance2?.clear();
3208
3240
  setRawMode(false);
3209
3241
  spawnSync2(cmd, [...extraArgs, tmpFile], { stdio: "inherit" });
3210
3242
  const content = readFileSync4(tmpFile, "utf-8");
@@ -3393,6 +3425,42 @@ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
3393
3425
  function isTerminal(name) {
3394
3426
  return TERMINAL_STATUS_RE2.test(name);
3395
3427
  }
3428
+ function handlePickerInput(input2, key, state) {
3429
+ if (key.escape) {
3430
+ state.onCancel();
3431
+ return;
3432
+ }
3433
+ if (key.return) {
3434
+ if (state.submittedRef.current) return;
3435
+ const opt = state.options[state.selectedIdx];
3436
+ if (!opt) return;
3437
+ if (isTerminal(opt.name) && state.showTerminalStatuses) {
3438
+ state.onConfirmTerminal();
3439
+ return;
3440
+ }
3441
+ state.submittedRef.current = true;
3442
+ state.onSelect(opt.id);
3443
+ return;
3444
+ }
3445
+ if (input2 === "j" || key.downArrow) {
3446
+ state.onNavigate((i) => Math.min(i + 1, state.options.length - 1));
3447
+ }
3448
+ if (input2 === "k" || key.upArrow) {
3449
+ state.onNavigate((i) => Math.max(i - 1, 0));
3450
+ }
3451
+ }
3452
+ function handleConfirmInput(input2, key, state) {
3453
+ if (input2 === "y" || input2 === "Y") {
3454
+ if (!state.submittedRef.current) {
3455
+ state.submittedRef.current = true;
3456
+ if (state.opt) state.onSelect(state.opt.id);
3457
+ }
3458
+ return;
3459
+ }
3460
+ if (input2 === "n" || input2 === "N" || key.escape) {
3461
+ state.onExitConfirm();
3462
+ }
3463
+ }
3396
3464
  function StatusPicker({
3397
3465
  options,
3398
3466
  currentStatus,
@@ -3408,38 +3476,24 @@ function StatusPicker({
3408
3476
  const submittedRef = useRef10(false);
3409
3477
  useInput10((input2, key) => {
3410
3478
  if (confirmingTerminal) {
3411
- if (input2 === "y" || input2 === "Y") {
3412
- if (submittedRef.current) return;
3413
- submittedRef.current = true;
3414
- const opt = options[selectedIdx];
3415
- if (opt) onSelect(opt.id);
3416
- return;
3417
- }
3418
- if (input2 === "n" || input2 === "N" || key.escape) {
3419
- setConfirmingTerminal(false);
3420
- return;
3421
- }
3422
- return;
3423
- }
3424
- if (key.escape) return onCancel();
3425
- if (key.return) {
3426
- if (submittedRef.current) return;
3427
- const opt = options[selectedIdx];
3428
- if (!opt) return;
3429
- if (isTerminal(opt.name) && showTerminalStatuses) {
3430
- setConfirmingTerminal(true);
3431
- return;
3432
- }
3433
- submittedRef.current = true;
3434
- onSelect(opt.id);
3479
+ handleConfirmInput(input2, key, {
3480
+ opt: options[selectedIdx],
3481
+ submittedRef,
3482
+ onSelect,
3483
+ onExitConfirm: () => setConfirmingTerminal(false)
3484
+ });
3435
3485
  return;
3436
3486
  }
3437
- if (input2 === "j" || key.downArrow) {
3438
- setSelectedIdx((i) => Math.min(i + 1, options.length - 1));
3439
- }
3440
- if (input2 === "k" || key.upArrow) {
3441
- setSelectedIdx((i) => Math.max(i - 1, 0));
3442
- }
3487
+ handlePickerInput(input2, key, {
3488
+ options,
3489
+ selectedIdx,
3490
+ showTerminalStatuses,
3491
+ submittedRef,
3492
+ onSelect,
3493
+ onCancel,
3494
+ onConfirmTerminal: () => setConfirmingTerminal(true),
3495
+ onNavigate: setSelectedIdx
3496
+ });
3443
3497
  });
3444
3498
  if (confirmingTerminal) {
3445
3499
  const opt = options[selectedIdx];
@@ -5805,7 +5859,7 @@ function resolveProjectId(projectId) {
5805
5859
  process.exit(1);
5806
5860
  }
5807
5861
  var program = new Command();
5808
- program.name("hog").description("Personal command deck \u2014 unified task dashboard for GitHub Projects + TickTick").version("1.6.0").option("--json", "Force JSON output").option("--human", "Force human-readable output").hook("preAction", (thisCommand) => {
5862
+ program.name("hog").description("Personal command deck \u2014 unified task dashboard for GitHub Projects + TickTick").version("1.6.2").option("--json", "Force JSON output").option("--human", "Force human-readable output").hook("preAction", (thisCommand) => {
5809
5863
  const opts = thisCommand.opts();
5810
5864
  if (opts.json) setFormat("json");
5811
5865
  if (opts.human) setFormat("human");