@ondrej-svec/hog 1.12.0 → 1.14.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.
- package/README.md +171 -106
- package/dist/cli.js +127 -60
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2014,7 +2014,8 @@ function useKeyboard({
|
|
|
2014
2014
|
activityNav,
|
|
2015
2015
|
onRepoEnter,
|
|
2016
2016
|
onStatusEnter,
|
|
2017
|
-
onActivityEnter
|
|
2017
|
+
onActivityEnter,
|
|
2018
|
+
showDetailPanel
|
|
2018
2019
|
}) {
|
|
2019
2020
|
const {
|
|
2020
2021
|
exit,
|
|
@@ -2115,7 +2116,11 @@ function useKeyboard({
|
|
|
2115
2116
|
if (ui.canAct) {
|
|
2116
2117
|
const digit = parseInt(input2, 10);
|
|
2117
2118
|
if (!Number.isNaN(digit) && digit >= 0 && digit <= 4) {
|
|
2118
|
-
|
|
2119
|
+
if (digit === 0 && !showDetailPanel) {
|
|
2120
|
+
ui.enterDetail();
|
|
2121
|
+
} else {
|
|
2122
|
+
panelFocus.focusPanel(digit);
|
|
2123
|
+
}
|
|
2119
2124
|
return;
|
|
2120
2125
|
}
|
|
2121
2126
|
if (input2 === "/") {
|
|
@@ -2721,6 +2726,9 @@ function uiReducer(state, action) {
|
|
|
2721
2726
|
case "ENTER_EDIT_ISSUE":
|
|
2722
2727
|
if (state.mode !== "normal") return state;
|
|
2723
2728
|
return { ...state, mode: "overlay:editIssue", previousMode: "normal" };
|
|
2729
|
+
case "ENTER_DETAIL":
|
|
2730
|
+
if (state.mode !== "normal") return state;
|
|
2731
|
+
return { ...state, mode: "overlay:detail", previousMode: "normal" };
|
|
2724
2732
|
case "TOGGLE_HELP":
|
|
2725
2733
|
return { ...state, helpVisible: !state.helpVisible };
|
|
2726
2734
|
case "EXIT_OVERLAY":
|
|
@@ -2765,6 +2773,7 @@ function useUIState() {
|
|
|
2765
2773
|
enterFocus: useCallback9(() => dispatch({ type: "ENTER_FOCUS" }), []),
|
|
2766
2774
|
enterFuzzyPicker: useCallback9(() => dispatch({ type: "ENTER_FUZZY_PICKER" }), []),
|
|
2767
2775
|
enterEditIssue: useCallback9(() => dispatch({ type: "ENTER_EDIT_ISSUE" }), []),
|
|
2776
|
+
enterDetail: useCallback9(() => dispatch({ type: "ENTER_DETAIL" }), []),
|
|
2768
2777
|
toggleHelp: useCallback9(() => dispatch({ type: "TOGGLE_HELP" }), []),
|
|
2769
2778
|
exitOverlay: useCallback9(() => dispatch({ type: "EXIT_OVERLAY" }), []),
|
|
2770
2779
|
exitToNormal: useCallback9(() => dispatch({ type: "EXIT_TO_NORMAL" }), []),
|
|
@@ -3095,6 +3104,12 @@ function HintBar({
|
|
|
3095
3104
|
if (uiMode === "overlay:fuzzyPicker") {
|
|
3096
3105
|
return /* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsx5(Text5, { color: "gray", children: "\u2191\u2193/Ctrl-J/K:nav Enter:jump Esc:close" }) });
|
|
3097
3106
|
}
|
|
3107
|
+
if (uiMode === "overlay:detail") {
|
|
3108
|
+
return /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
3109
|
+
/* @__PURE__ */ jsx5(Text5, { color: "cyan", bold: true, children: "[DETAIL]" }),
|
|
3110
|
+
/* @__PURE__ */ jsx5(Text5, { color: "gray", children: " Esc:close e:edit c:comment y:copy-link ? help" })
|
|
3111
|
+
] });
|
|
3112
|
+
}
|
|
3098
3113
|
if (uiMode.startsWith("overlay:")) {
|
|
3099
3114
|
return /* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsx5(Text5, { color: "gray", children: "j/k:nav Enter:select Esc:cancel" }) });
|
|
3100
3115
|
}
|
|
@@ -4162,6 +4177,7 @@ var init_help_overlay = __esm({
|
|
|
4162
4177
|
category: "View",
|
|
4163
4178
|
items: [
|
|
4164
4179
|
{ key: "Enter", desc: "Open issue in browser" },
|
|
4180
|
+
{ key: "0", desc: "Detail panel (full-screen on narrow terminals)" },
|
|
4165
4181
|
{ key: "Space", desc: "Multi-select item" },
|
|
4166
4182
|
{ key: "/", desc: "Search (inline filter)" },
|
|
4167
4183
|
{ key: "F", desc: "Fuzzy find issue (telescope-style)" },
|
|
@@ -4845,47 +4861,69 @@ var init_repos_panel = __esm({
|
|
|
4845
4861
|
|
|
4846
4862
|
// src/board/components/issue-row.tsx
|
|
4847
4863
|
import { Box as Box20, Text as Text19 } from "ink";
|
|
4848
|
-
import {
|
|
4864
|
+
import { jsx as jsx21, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
4849
4865
|
function truncate(s, max) {
|
|
4850
4866
|
return s.length > max ? `${s.slice(0, max - 1)}\u2026` : s;
|
|
4851
4867
|
}
|
|
4852
|
-
function
|
|
4853
|
-
if (
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
}
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
if (seconds < 60) return "now";
|
|
4868
|
+
function formatDate2(issue) {
|
|
4869
|
+
if (issue.targetDate) {
|
|
4870
|
+
const d = new Date(issue.targetDate);
|
|
4871
|
+
const days2 = Math.ceil((d.getTime() - Date.now()) / 864e5);
|
|
4872
|
+
if (days2 < 0) return { text: `${Math.abs(days2)}d overdue`, color: "red" };
|
|
4873
|
+
if (days2 === 0) return { text: "today", color: "yellow" };
|
|
4874
|
+
if (days2 === 1) return { text: "tomorrow", color: "white" };
|
|
4875
|
+
if (days2 <= 7) return { text: `in ${days2}d`, color: "white" };
|
|
4876
|
+
return {
|
|
4877
|
+
text: d.toLocaleDateString("en-US", { month: "short", day: "numeric" }),
|
|
4878
|
+
color: "gray"
|
|
4879
|
+
};
|
|
4880
|
+
}
|
|
4881
|
+
const seconds = Math.floor((Date.now() - new Date(issue.updatedAt).getTime()) / 1e3);
|
|
4882
|
+
if (seconds < 60) return { text: "now", color: "gray" };
|
|
4868
4883
|
const minutes = Math.floor(seconds / 60);
|
|
4869
|
-
if (minutes < 60) return `${minutes}m
|
|
4884
|
+
if (minutes < 60) return { text: `${minutes}m`, color: "gray" };
|
|
4870
4885
|
const hours = Math.floor(minutes / 60);
|
|
4871
|
-
if (hours < 24) return `${hours}h
|
|
4886
|
+
if (hours < 24) return { text: `${hours}h`, color: "gray" };
|
|
4872
4887
|
const days = Math.floor(hours / 24);
|
|
4873
|
-
if (days < 30) return `${days}d
|
|
4888
|
+
if (days < 30) return { text: `${days}d`, color: "gray" };
|
|
4874
4889
|
const months = Math.floor(days / 30);
|
|
4875
|
-
return `${months}mo
|
|
4890
|
+
return { text: `${months}mo`, color: "gray" };
|
|
4891
|
+
}
|
|
4892
|
+
function compactLabel(name) {
|
|
4893
|
+
const lc = name.toLowerCase();
|
|
4894
|
+
const colon = lc.indexOf(":");
|
|
4895
|
+
if (colon < 0) return PLAIN_ABBREVS[lc] ?? name.slice(0, 5);
|
|
4896
|
+
const key = lc.slice(0, colon);
|
|
4897
|
+
const val = name.slice(colon + 1);
|
|
4898
|
+
if (key === "size") return val.slice(0, 3).toUpperCase();
|
|
4899
|
+
if (key === "priority") return `p:${val.slice(0, 1).toUpperCase()}`;
|
|
4900
|
+
if (key === "work") return "WIP";
|
|
4901
|
+
return `${key.slice(0, 2)}:${val.slice(0, 2)}`;
|
|
4876
4902
|
}
|
|
4877
4903
|
function labelColor(name) {
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4904
|
+
const lc = name.toLowerCase();
|
|
4905
|
+
if (lc === "bug" || lc === "urgent" || lc.startsWith("priority:h") || lc.startsWith("priority:c"))
|
|
4906
|
+
return "red";
|
|
4907
|
+
if (lc.startsWith("priority:m") || lc.startsWith("work:")) return "yellow";
|
|
4908
|
+
if (lc.startsWith("priority:l") || lc === "wontfix") return "gray";
|
|
4909
|
+
if (lc.startsWith("size:")) return "white";
|
|
4910
|
+
if (lc === "feature" || lc === "enhancement") return "green";
|
|
4911
|
+
if (lc === "documentation") return "blue";
|
|
4912
|
+
if (lc === "good first issue") return "magenta";
|
|
4913
|
+
return "cyan";
|
|
4914
|
+
}
|
|
4915
|
+
function IssueRow({ issue, selfLogin, isSelected, panelWidth }) {
|
|
4881
4916
|
const assignees = issue.assignees ?? [];
|
|
4882
4917
|
const isSelf = assignees.some((a) => a.login === selfLogin);
|
|
4883
4918
|
const isUnassigned = assignees.length === 0;
|
|
4884
4919
|
const assigneeColor = isSelf ? "green" : isUnassigned ? "gray" : "white";
|
|
4885
|
-
const assigneeText = isUnassigned ? "unassigned" : truncate(assignees.map((a) => a.login).join(", "),
|
|
4920
|
+
const assigneeText = isUnassigned ? "unassigned" : truncate(assignees.map((a) => a.login).join(", "), ASSIGN_W);
|
|
4886
4921
|
const labels = (issue.labels ?? []).slice(0, 2);
|
|
4887
|
-
const
|
|
4888
|
-
const
|
|
4922
|
+
const date = formatDate2(issue);
|
|
4923
|
+
const innerW = panelWidth - 2;
|
|
4924
|
+
const titleW = Math.max(8, innerW - FIXED_OVERHEAD);
|
|
4925
|
+
const titleStr = truncate(issue.title, titleW).padEnd(titleW);
|
|
4926
|
+
const dateStr = date.text.padStart(DATE_W);
|
|
4889
4927
|
return /* @__PURE__ */ jsxs21(Box20, { children: [
|
|
4890
4928
|
isSelected ? /* @__PURE__ */ jsx21(Text19, { color: "cyan", bold: true, children: "\u25B6 " }) : /* @__PURE__ */ jsx21(Text19, { children: " " }),
|
|
4891
4929
|
/* @__PURE__ */ jsxs21(Text19, { color: "cyan", children: [
|
|
@@ -4893,49 +4931,57 @@ function IssueRow({ issue, selfLogin, isSelected }) {
|
|
|
4893
4931
|
String(issue.number).padEnd(5)
|
|
4894
4932
|
] }),
|
|
4895
4933
|
/* @__PURE__ */ jsx21(Text19, { children: " " }),
|
|
4896
|
-
isSelected ? /* @__PURE__ */ jsx21(Text19, { color: "white",
|
|
4934
|
+
isSelected ? /* @__PURE__ */ jsx21(Text19, { bold: true, color: "white", children: titleStr }) : /* @__PURE__ */ jsx21(Text19, { children: titleStr }),
|
|
4897
4935
|
/* @__PURE__ */ jsx21(Text19, { children: " " }),
|
|
4898
|
-
/* @__PURE__ */ jsx21(Box20, { width:
|
|
4936
|
+
/* @__PURE__ */ jsx21(Box20, { width: LABEL_W, overflow: "hidden", children: labels.length === 0 ? /* @__PURE__ */ jsx21(Text19, { color: "gray", children: " ".repeat(LABEL_W) }) : labels.map((l, i) => /* @__PURE__ */ jsxs21(Text19, { children: [
|
|
4899
4937
|
i > 0 ? " " : "",
|
|
4900
4938
|
/* @__PURE__ */ jsxs21(Text19, { color: labelColor(l.name), children: [
|
|
4901
4939
|
"[",
|
|
4902
|
-
|
|
4940
|
+
compactLabel(l.name),
|
|
4903
4941
|
"]"
|
|
4904
4942
|
] })
|
|
4905
4943
|
] }, l.name)) }),
|
|
4906
4944
|
/* @__PURE__ */ jsx21(Text19, { children: " " }),
|
|
4907
|
-
/* @__PURE__ */ jsx21(Text19, { color: assigneeColor, children: assigneeText.padEnd(
|
|
4945
|
+
/* @__PURE__ */ jsx21(Text19, { color: assigneeColor, children: assigneeText.padEnd(ASSIGN_W) }),
|
|
4908
4946
|
/* @__PURE__ */ jsx21(Text19, { children: " " }),
|
|
4909
|
-
/* @__PURE__ */ jsx21(Text19, { color:
|
|
4910
|
-
target.text ? /* @__PURE__ */ jsxs21(Fragment3, { children: [
|
|
4911
|
-
/* @__PURE__ */ jsx21(Text19, { children: " " }),
|
|
4912
|
-
/* @__PURE__ */ jsx21(Text19, { color: target.color, children: target.text })
|
|
4913
|
-
] }) : null
|
|
4947
|
+
/* @__PURE__ */ jsx21(Text19, { color: date.color, children: dateStr })
|
|
4914
4948
|
] });
|
|
4915
4949
|
}
|
|
4916
|
-
var
|
|
4950
|
+
var PLAIN_ABBREVS, CURSOR_W, NUM_W, LABEL_W, ASSIGN_W, DATE_W, FIXED_OVERHEAD;
|
|
4917
4951
|
var init_issue_row = __esm({
|
|
4918
4952
|
"src/board/components/issue-row.tsx"() {
|
|
4919
4953
|
"use strict";
|
|
4920
|
-
|
|
4921
|
-
bug: "
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
documentation: "
|
|
4925
|
-
"good first issue": "
|
|
4926
|
-
help: "
|
|
4927
|
-
question: "
|
|
4928
|
-
urgent: "
|
|
4929
|
-
wontfix: "
|
|
4954
|
+
PLAIN_ABBREVS = {
|
|
4955
|
+
bug: "bug",
|
|
4956
|
+
feature: "feat",
|
|
4957
|
+
enhancement: "enh",
|
|
4958
|
+
documentation: "docs",
|
|
4959
|
+
"good first issue": "gfi",
|
|
4960
|
+
help: "help",
|
|
4961
|
+
question: "?",
|
|
4962
|
+
urgent: "urg!",
|
|
4963
|
+
wontfix: "wont",
|
|
4964
|
+
task: "task"
|
|
4930
4965
|
};
|
|
4931
|
-
|
|
4966
|
+
CURSOR_W = 2;
|
|
4967
|
+
NUM_W = 7;
|
|
4968
|
+
LABEL_W = 13;
|
|
4969
|
+
ASSIGN_W = 10;
|
|
4970
|
+
DATE_W = 10;
|
|
4971
|
+
FIXED_OVERHEAD = CURSOR_W + NUM_W + 1 + LABEL_W + 1 + ASSIGN_W + 1 + DATE_W;
|
|
4932
4972
|
}
|
|
4933
4973
|
});
|
|
4934
4974
|
|
|
4935
4975
|
// src/board/components/row-renderer.tsx
|
|
4936
4976
|
import { Box as Box21, Text as Text20 } from "ink";
|
|
4937
4977
|
import { jsx as jsx22, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
4938
|
-
function RowRenderer({
|
|
4978
|
+
function RowRenderer({
|
|
4979
|
+
row,
|
|
4980
|
+
selectedId,
|
|
4981
|
+
selfLogin,
|
|
4982
|
+
isMultiSelected,
|
|
4983
|
+
panelWidth = 120
|
|
4984
|
+
}) {
|
|
4939
4985
|
switch (row.type) {
|
|
4940
4986
|
case "sectionHeader": {
|
|
4941
4987
|
const arrow = row.isCollapsed ? "\u25B6" : "\u25BC";
|
|
@@ -4990,7 +5036,15 @@ function RowRenderer({ row, selectedId, selfLogin, isMultiSelected }) {
|
|
|
4990
5036
|
const checkbox2 = isMultiSelected != null ? isMultiSelected ? "\u2611 " : "\u2610 " : "";
|
|
4991
5037
|
return /* @__PURE__ */ jsxs22(Box21, { children: [
|
|
4992
5038
|
checkbox2 ? /* @__PURE__ */ jsx22(Text20, { color: isMultiSelected ? "cyan" : "gray", children: checkbox2 }) : null,
|
|
4993
|
-
/* @__PURE__ */ jsx22(
|
|
5039
|
+
/* @__PURE__ */ jsx22(
|
|
5040
|
+
IssueRow,
|
|
5041
|
+
{
|
|
5042
|
+
issue: row.issue,
|
|
5043
|
+
selfLogin,
|
|
5044
|
+
isSelected: selectedId === row.navId,
|
|
5045
|
+
panelWidth
|
|
5046
|
+
}
|
|
5047
|
+
)
|
|
4994
5048
|
] });
|
|
4995
5049
|
}
|
|
4996
5050
|
case "activity": {
|
|
@@ -5065,10 +5119,10 @@ var init_statuses_panel = __esm({
|
|
|
5065
5119
|
// src/board/components/toast-container.tsx
|
|
5066
5120
|
import { Spinner as Spinner3 } from "@inkjs/ui";
|
|
5067
5121
|
import { Box as Box23, Text as Text22 } from "ink";
|
|
5068
|
-
import { Fragment as
|
|
5122
|
+
import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
5069
5123
|
function ToastContainer({ toasts }) {
|
|
5070
5124
|
if (toasts.length === 0) return null;
|
|
5071
|
-
return /* @__PURE__ */ jsx24(Box23, { flexDirection: "column", children: toasts.map((t) => /* @__PURE__ */ jsx24(Box23, { children: t.type === "loading" ? /* @__PURE__ */ jsxs24(
|
|
5125
|
+
return /* @__PURE__ */ jsx24(Box23, { flexDirection: "column", children: toasts.map((t) => /* @__PURE__ */ jsx24(Box23, { children: t.type === "loading" ? /* @__PURE__ */ jsxs24(Fragment3, { children: [
|
|
5072
5126
|
/* @__PURE__ */ jsx24(Spinner3, { label: "" }),
|
|
5073
5127
|
/* @__PURE__ */ jsxs24(Text22, { color: "cyan", children: [
|
|
5074
5128
|
" ",
|
|
@@ -5104,7 +5158,7 @@ import { execFileSync as execFileSync3, spawnSync as spawnSync4 } from "child_pr
|
|
|
5104
5158
|
import { Spinner as Spinner4 } from "@inkjs/ui";
|
|
5105
5159
|
import { Box as Box24, Text as Text23, useApp, useStdout } from "ink";
|
|
5106
5160
|
import { useCallback as useCallback12, useEffect as useEffect9, useMemo as useMemo3, useRef as useRef13, useState as useState16 } from "react";
|
|
5107
|
-
import { Fragment as
|
|
5161
|
+
import { Fragment as Fragment4, jsx as jsx25, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
5108
5162
|
function resolveStatusGroups(statusOptions, configuredGroups) {
|
|
5109
5163
|
if (configuredGroups && configuredGroups.length > 0) {
|
|
5110
5164
|
return configuredGroups.map((entry) => {
|
|
@@ -5740,7 +5794,8 @@ function Dashboard({ config: config2, options, activeProfile }) {
|
|
|
5740
5794
|
activityNav,
|
|
5741
5795
|
onRepoEnter,
|
|
5742
5796
|
onStatusEnter,
|
|
5743
|
-
onActivityEnter
|
|
5797
|
+
onActivityEnter,
|
|
5798
|
+
showDetailPanel
|
|
5744
5799
|
});
|
|
5745
5800
|
if (status === "loading" && !data) {
|
|
5746
5801
|
return /* @__PURE__ */ jsx25(Box24, { flexDirection: "column", padding: 1, children: /* @__PURE__ */ jsx25(Spinner4, { label: "Loading dashboard..." }) });
|
|
@@ -5801,6 +5856,7 @@ function Dashboard({ config: config2, options, activeProfile }) {
|
|
|
5801
5856
|
row,
|
|
5802
5857
|
selectedId: nav.selectedId,
|
|
5803
5858
|
selfLogin: config2.board.assignee,
|
|
5859
|
+
panelWidth: issuesPanelWidth,
|
|
5804
5860
|
isMultiSelected: ui.state.mode === "multiSelect" && row.navId ? multiSelect.isSelected(row.navId) : void 0
|
|
5805
5861
|
},
|
|
5806
5862
|
row.key
|
|
@@ -5851,10 +5907,10 @@ function Dashboard({ config: config2, options, activeProfile }) {
|
|
|
5851
5907
|
dateStr
|
|
5852
5908
|
] }),
|
|
5853
5909
|
/* @__PURE__ */ jsx25(Text23, { children: " " }),
|
|
5854
|
-
isRefreshing ? /* @__PURE__ */ jsxs25(
|
|
5910
|
+
isRefreshing ? /* @__PURE__ */ jsxs25(Fragment4, { children: [
|
|
5855
5911
|
/* @__PURE__ */ jsx25(Spinner4, { label: "" }),
|
|
5856
5912
|
/* @__PURE__ */ jsx25(Text23, { color: "cyan", children: " Refreshing..." })
|
|
5857
|
-
] }) : /* @__PURE__ */ jsxs25(
|
|
5913
|
+
] }) : /* @__PURE__ */ jsxs25(Fragment4, { children: [
|
|
5858
5914
|
/* @__PURE__ */ jsx25(RefreshAge, { lastRefresh }),
|
|
5859
5915
|
consecutiveFailures > 0 ? /* @__PURE__ */ jsx25(Text23, { color: "red", children: " (!)" }) : null
|
|
5860
5916
|
] }),
|
|
@@ -5906,7 +5962,18 @@ function Dashboard({ config: config2, options, activeProfile }) {
|
|
|
5906
5962
|
onPushEntry: pushEntry
|
|
5907
5963
|
}
|
|
5908
5964
|
),
|
|
5909
|
-
|
|
5965
|
+
ui.state.mode === "overlay:detail" ? /* @__PURE__ */ jsx25(
|
|
5966
|
+
DetailPanel,
|
|
5967
|
+
{
|
|
5968
|
+
issue: selectedItem.issue,
|
|
5969
|
+
width: termSize.cols,
|
|
5970
|
+
isActive: true,
|
|
5971
|
+
issueRepo: selectedItem.repoName,
|
|
5972
|
+
fetchComments: handleFetchComments,
|
|
5973
|
+
commentsState: currentCommentsState
|
|
5974
|
+
}
|
|
5975
|
+
) : null,
|
|
5976
|
+
!ui.state.helpVisible && ui.state.mode !== "overlay:status" && ui.state.mode !== "overlay:create" && ui.state.mode !== "overlay:createNl" && ui.state.mode !== "overlay:bulkAction" && ui.state.mode !== "overlay:confirmPick" && ui.state.mode !== "overlay:detail" && ui.state.mode !== "focus" ? /* @__PURE__ */ jsx25(
|
|
5910
5977
|
PanelLayout,
|
|
5911
5978
|
{
|
|
5912
5979
|
cols: termSize.cols,
|
|
@@ -7142,7 +7209,7 @@ function resolveProjectId(projectId) {
|
|
|
7142
7209
|
process.exit(1);
|
|
7143
7210
|
}
|
|
7144
7211
|
var program = new Command();
|
|
7145
|
-
program.name("hog").description("Personal command deck \u2014 unified task dashboard for GitHub Projects + TickTick").version("1.
|
|
7212
|
+
program.name("hog").description("Personal command deck \u2014 unified task dashboard for GitHub Projects + TickTick").version("1.14.0").option("--json", "Force JSON output").option("--human", "Force human-readable output").hook("preAction", (thisCommand) => {
|
|
7146
7213
|
const opts = thisCommand.opts();
|
|
7147
7214
|
if (opts.json) setFormat("json");
|
|
7148
7215
|
if (opts.human) setFormat("human");
|