@ondrej-svec/hog 1.22.0 → 1.23.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/dist/cli.js +116 -125
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2942,12 +2942,41 @@ function useKeyboard({
|
|
|
2942
2942
|
nav.moveUp();
|
|
2943
2943
|
return;
|
|
2944
2944
|
}
|
|
2945
|
+
if (input2 === "q") {
|
|
2946
|
+
exit();
|
|
2947
|
+
return;
|
|
2948
|
+
}
|
|
2949
|
+
if (input2 === "/") {
|
|
2950
|
+
multiSelect.clear();
|
|
2951
|
+
ui.enterSearch();
|
|
2952
|
+
return;
|
|
2953
|
+
}
|
|
2954
|
+
if (input2 === "t") {
|
|
2955
|
+
handleToggleMine();
|
|
2956
|
+
return;
|
|
2957
|
+
}
|
|
2958
|
+
if (input2 === "F") {
|
|
2959
|
+
handleEnterFuzzyPicker();
|
|
2960
|
+
return;
|
|
2961
|
+
}
|
|
2945
2962
|
if (input2 === "C") {
|
|
2946
2963
|
handleLaunchClaude();
|
|
2947
2964
|
return;
|
|
2948
2965
|
}
|
|
2949
|
-
if (input2 === "
|
|
2950
|
-
|
|
2966
|
+
if (input2 === "y") {
|
|
2967
|
+
handleCopyLink();
|
|
2968
|
+
return;
|
|
2969
|
+
}
|
|
2970
|
+
if (input2 === "o") {
|
|
2971
|
+
handleSlack();
|
|
2972
|
+
return;
|
|
2973
|
+
}
|
|
2974
|
+
if (input2 === "g") {
|
|
2975
|
+
handleOpen();
|
|
2976
|
+
return;
|
|
2977
|
+
}
|
|
2978
|
+
if (input2 === "r" || input2 === "R") {
|
|
2979
|
+
refresh();
|
|
2951
2980
|
return;
|
|
2952
2981
|
}
|
|
2953
2982
|
return;
|
|
@@ -4081,42 +4110,6 @@ function isPaneAlive(paneId) {
|
|
|
4081
4110
|
return false;
|
|
4082
4111
|
}
|
|
4083
4112
|
}
|
|
4084
|
-
function splitWithInfo(info, widthPercent) {
|
|
4085
|
-
try {
|
|
4086
|
-
const paneId = execFileSync3(
|
|
4087
|
-
"tmux",
|
|
4088
|
-
[
|
|
4089
|
-
"split-window",
|
|
4090
|
-
"-h",
|
|
4091
|
-
"-l",
|
|
4092
|
-
`${widthPercent}%`,
|
|
4093
|
-
"-d",
|
|
4094
|
-
"-P",
|
|
4095
|
-
"-F",
|
|
4096
|
-
"#{pane_id}",
|
|
4097
|
-
"printf",
|
|
4098
|
-
"Issue: %s\\n\\nURL: %s\\n\\nNo Claude Code session active.\\nPress C to launch one.\\n",
|
|
4099
|
-
info.title,
|
|
4100
|
-
info.url
|
|
4101
|
-
],
|
|
4102
|
-
{
|
|
4103
|
-
encoding: "utf-8",
|
|
4104
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
4105
|
-
}
|
|
4106
|
-
);
|
|
4107
|
-
return paneId.trim() || null;
|
|
4108
|
-
} catch {
|
|
4109
|
-
return null;
|
|
4110
|
-
}
|
|
4111
|
-
}
|
|
4112
|
-
function killPane(paneId) {
|
|
4113
|
-
try {
|
|
4114
|
-
execFileSync3("tmux", ["kill-pane", "-t", paneId], {
|
|
4115
|
-
stdio: "ignore"
|
|
4116
|
-
});
|
|
4117
|
-
} catch {
|
|
4118
|
-
}
|
|
4119
|
-
}
|
|
4120
4113
|
var init_tmux_pane = __esm({
|
|
4121
4114
|
"src/board/tmux-pane.ts"() {
|
|
4122
4115
|
"use strict";
|
|
@@ -4125,32 +4118,16 @@ var init_tmux_pane = __esm({
|
|
|
4125
4118
|
|
|
4126
4119
|
// src/board/hooks/use-zen-mode.ts
|
|
4127
4120
|
import { useCallback as useCallback13, useEffect as useEffect5, useRef as useRef11, useState as useState7 } from "react";
|
|
4128
|
-
function
|
|
4121
|
+
function issueNumberFromId(selectedId) {
|
|
4129
4122
|
if (!selectedId?.startsWith("gh:")) return null;
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
return { issue, repoName: rd.repo.name };
|
|
4134
|
-
}
|
|
4135
|
-
}
|
|
4136
|
-
return null;
|
|
4137
|
-
}
|
|
4138
|
-
function cleanupPane(paneId, isAgent) {
|
|
4139
|
-
if (isAgent) {
|
|
4140
|
-
breakPane(paneId);
|
|
4141
|
-
} else {
|
|
4142
|
-
killPane(paneId);
|
|
4143
|
-
}
|
|
4123
|
+
const parts = selectedId.split(":");
|
|
4124
|
+
const num = Number(parts[2]);
|
|
4125
|
+
return Number.isNaN(num) ? null : num;
|
|
4144
4126
|
}
|
|
4145
|
-
function
|
|
4146
|
-
const winName = agentWindowName(
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
const paneId2 = joinAgentPane(winName, ZEN_PANE_WIDTH_PERCENT);
|
|
4150
|
-
return paneId2 ? { paneId: paneId2, isAgent: true } : null;
|
|
4151
|
-
}
|
|
4152
|
-
const paneId = splitWithInfo({ title: issue.title, url: issue.url }, ZEN_PANE_WIDTH_PERCENT);
|
|
4153
|
-
return paneId ? { paneId, isAgent: false } : null;
|
|
4127
|
+
function tryJoinAgent(issueNumber) {
|
|
4128
|
+
const winName = agentWindowName(issueNumber);
|
|
4129
|
+
if (!windowExists(winName)) return null;
|
|
4130
|
+
return joinAgentPane(winName, ZEN_PANE_WIDTH_PERCENT);
|
|
4154
4131
|
}
|
|
4155
4132
|
function useZenMode({
|
|
4156
4133
|
ui,
|
|
@@ -4160,21 +4137,19 @@ function useZenMode({
|
|
|
4160
4137
|
selectedId
|
|
4161
4138
|
}) {
|
|
4162
4139
|
const [zenPaneId, setZenPaneId] = useState7(null);
|
|
4163
|
-
const
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
});
|
|
4168
|
-
paneRef.current = { id: zenPaneId, isAgent: zenIsAgentPane };
|
|
4169
|
-
const exitZen = useCallback13(() => {
|
|
4170
|
-
const { id, isAgent } = paneRef.current;
|
|
4140
|
+
const paneRef = useRef11(null);
|
|
4141
|
+
paneRef.current = zenPaneId;
|
|
4142
|
+
const cleanupCurrentPane = useCallback13(() => {
|
|
4143
|
+
const id = paneRef.current;
|
|
4171
4144
|
if (id) {
|
|
4172
|
-
|
|
4145
|
+
breakPane(id);
|
|
4173
4146
|
setZenPaneId(null);
|
|
4174
|
-
setZenIsAgentPane(false);
|
|
4175
4147
|
}
|
|
4148
|
+
}, []);
|
|
4149
|
+
const exitZen = useCallback13(() => {
|
|
4150
|
+
cleanupCurrentPane();
|
|
4176
4151
|
ui.exitZen();
|
|
4177
|
-
}, [ui]);
|
|
4152
|
+
}, [ui, cleanupCurrentPane]);
|
|
4178
4153
|
const handleToggleZen = useCallback13(() => {
|
|
4179
4154
|
if (ui.state.mode === "zen") {
|
|
4180
4155
|
exitZen();
|
|
@@ -4188,70 +4163,54 @@ function useZenMode({
|
|
|
4188
4163
|
toast.error("Terminal too narrow for Zen mode");
|
|
4189
4164
|
return;
|
|
4190
4165
|
}
|
|
4191
|
-
const
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
return;
|
|
4166
|
+
const issueNum = issueNumberFromId(selectedId);
|
|
4167
|
+
if (issueNum) {
|
|
4168
|
+
const paneId = tryJoinAgent(issueNum);
|
|
4169
|
+
if (paneId) setZenPaneId(paneId);
|
|
4196
4170
|
}
|
|
4197
|
-
setZenPaneId(result.paneId);
|
|
4198
|
-
setZenIsAgentPane(result.isAgent);
|
|
4199
4171
|
ui.enterZen();
|
|
4200
|
-
}, [ui, toast, termCols, exitZen,
|
|
4172
|
+
}, [ui, toast, termCols, exitZen, selectedId]);
|
|
4201
4173
|
const swapToAgent = useCallback13(
|
|
4202
4174
|
(issueNumber) => {
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
cleanupPane(id, isAgent);
|
|
4175
|
+
if (ui.state.mode !== "zen") return;
|
|
4176
|
+
cleanupCurrentPane();
|
|
4206
4177
|
setTimeout(() => {
|
|
4207
|
-
const
|
|
4208
|
-
if (
|
|
4209
|
-
const newPaneId = joinAgentPane(winName, ZEN_PANE_WIDTH_PERCENT);
|
|
4210
|
-
setZenPaneId(newPaneId);
|
|
4211
|
-
setZenIsAgentPane(true);
|
|
4212
|
-
}
|
|
4178
|
+
const paneId = tryJoinAgent(issueNumber);
|
|
4179
|
+
if (paneId) setZenPaneId(paneId);
|
|
4213
4180
|
}, 500);
|
|
4214
4181
|
},
|
|
4215
|
-
[ui.state.mode]
|
|
4182
|
+
[ui.state.mode, cleanupCurrentPane]
|
|
4216
4183
|
);
|
|
4217
4184
|
const prevSelectedRef = useRef11(null);
|
|
4218
4185
|
useEffect5(() => {
|
|
4219
|
-
if (ui.state.mode !== "zen"
|
|
4186
|
+
if (ui.state.mode !== "zen") {
|
|
4220
4187
|
prevSelectedRef.current = selectedId;
|
|
4221
4188
|
return;
|
|
4222
4189
|
}
|
|
4223
4190
|
if (selectedId === prevSelectedRef.current) return;
|
|
4224
4191
|
prevSelectedRef.current = selectedId;
|
|
4225
4192
|
const timer = setTimeout(() => {
|
|
4226
|
-
const
|
|
4227
|
-
if (
|
|
4228
|
-
|
|
4229
|
-
if (!found) return;
|
|
4230
|
-
cleanupPane(id, isAgent);
|
|
4231
|
-
const result = openOrSplitPane(found.issue);
|
|
4232
|
-
if (!result) {
|
|
4233
|
-
setZenPaneId(null);
|
|
4234
|
-
setZenIsAgentPane(false);
|
|
4235
|
-
ui.exitZen();
|
|
4236
|
-
toast.error("Zen pane lost \u2014 exiting zen mode");
|
|
4237
|
-
return;
|
|
4193
|
+
const currentId = paneRef.current;
|
|
4194
|
+
if (currentId) {
|
|
4195
|
+
breakPane(currentId);
|
|
4238
4196
|
}
|
|
4239
|
-
|
|
4240
|
-
|
|
4197
|
+
const issueNum = issueNumberFromId(selectedId);
|
|
4198
|
+
const newPaneId = issueNum ? tryJoinAgent(issueNum) : null;
|
|
4199
|
+
setZenPaneId(newPaneId);
|
|
4241
4200
|
}, CURSOR_FOLLOW_DEBOUNCE_MS);
|
|
4242
4201
|
return () => clearTimeout(timer);
|
|
4243
|
-
}, [ui.state.mode,
|
|
4202
|
+
}, [ui.state.mode, selectedId, repos]);
|
|
4244
4203
|
useEffect5(() => {
|
|
4245
4204
|
if (ui.state.mode !== "zen" || !zenPaneId) return;
|
|
4246
4205
|
const interval = setInterval(() => {
|
|
4247
4206
|
if (!isPaneAlive(zenPaneId)) {
|
|
4248
|
-
|
|
4249
|
-
toast.info("
|
|
4207
|
+
setZenPaneId(null);
|
|
4208
|
+
toast.info("Agent pane closed");
|
|
4250
4209
|
}
|
|
4251
4210
|
}, DEAD_PANE_CHECK_MS);
|
|
4252
4211
|
return () => clearInterval(interval);
|
|
4253
|
-
}, [ui.state.mode, zenPaneId,
|
|
4254
|
-
return { zenPaneId,
|
|
4212
|
+
}, [ui.state.mode, zenPaneId, toast]);
|
|
4213
|
+
return { zenPaneId, handleToggleZen, swapToAgent };
|
|
4255
4214
|
}
|
|
4256
4215
|
var ZEN_PANE_WIDTH_PERCENT, ZEN_MIN_COLS, CURSOR_FOLLOW_DEBOUNCE_MS, DEAD_PANE_CHECK_MS;
|
|
4257
4216
|
var init_use_zen_mode = __esm({
|
|
@@ -4260,7 +4219,7 @@ var init_use_zen_mode = __esm({
|
|
|
4260
4219
|
init_tmux_pane();
|
|
4261
4220
|
ZEN_PANE_WIDTH_PERCENT = 65;
|
|
4262
4221
|
ZEN_MIN_COLS = 100;
|
|
4263
|
-
CURSOR_FOLLOW_DEBOUNCE_MS =
|
|
4222
|
+
CURSOR_FOLLOW_DEBOUNCE_MS = 200;
|
|
4264
4223
|
DEAD_PANE_CHECK_MS = 2e3;
|
|
4265
4224
|
}
|
|
4266
4225
|
});
|
|
@@ -4607,7 +4566,10 @@ function HintBar({
|
|
|
4607
4566
|
if (uiMode === "zen") {
|
|
4608
4567
|
return /* @__PURE__ */ jsxs6(Box6, { children: [
|
|
4609
4568
|
/* @__PURE__ */ jsx6(Text6, { color: "green", bold: true, children: "[ZEN]" }),
|
|
4610
|
-
/* @__PURE__ */
|
|
4569
|
+
/* @__PURE__ */ jsxs6(Text6, { color: "gray", children: [
|
|
4570
|
+
" ",
|
|
4571
|
+
"j/k:nav /:search t:mine F:find C:claude y:copy g:open r:refresh Z/Esc:exit q:quit"
|
|
4572
|
+
] })
|
|
4611
4573
|
] });
|
|
4612
4574
|
}
|
|
4613
4575
|
if (uiMode === "focus") {
|
|
@@ -8313,17 +8275,46 @@ function Dashboard({ config: config2, options, activeProfile }) {
|
|
|
8313
8275
|
commentsState: currentCommentsState
|
|
8314
8276
|
}
|
|
8315
8277
|
) : null,
|
|
8316
|
-
ui.state.mode === "zen" ?
|
|
8317
|
-
|
|
8318
|
-
{
|
|
8319
|
-
|
|
8320
|
-
|
|
8321
|
-
|
|
8322
|
-
|
|
8323
|
-
|
|
8324
|
-
|
|
8325
|
-
|
|
8326
|
-
|
|
8278
|
+
ui.state.mode === "zen" ? zen.zenPaneId ? (
|
|
8279
|
+
// Agent pane is joined — show narrow issue list (agent fills the rest via tmux)
|
|
8280
|
+
/* @__PURE__ */ jsx29(Box28, { flexDirection: "column", height: issuesPanelHeight + ACTIVITY_HEIGHT, children: /* @__PURE__ */ jsx29(Panel, { title: "Issues (Zen)", isActive: true, width: usableWidth, children: visibleRows.map((row) => /* @__PURE__ */ jsx29(
|
|
8281
|
+
RowRenderer,
|
|
8282
|
+
{
|
|
8283
|
+
row,
|
|
8284
|
+
selectedId: nav.selectedId,
|
|
8285
|
+
selfLogin: config2.board.assignee,
|
|
8286
|
+
panelWidth: usableWidth,
|
|
8287
|
+
stalenessConfig: config2.board.workflow?.staleness
|
|
8288
|
+
},
|
|
8289
|
+
row.key
|
|
8290
|
+
)) }) })
|
|
8291
|
+
) : (
|
|
8292
|
+
// No agent — show issue list + detail panel side by side
|
|
8293
|
+
/* @__PURE__ */ jsxs29(Box28, { flexDirection: "row", height: issuesPanelHeight + ACTIVITY_HEIGHT, children: [
|
|
8294
|
+
/* @__PURE__ */ jsx29(Box28, { flexDirection: "column", width: issuesPanelWidth, children: /* @__PURE__ */ jsx29(Panel, { title: "Issues (Zen)", isActive: true, width: issuesPanelWidth, children: visibleRows.map((row) => /* @__PURE__ */ jsx29(
|
|
8295
|
+
RowRenderer,
|
|
8296
|
+
{
|
|
8297
|
+
row,
|
|
8298
|
+
selectedId: nav.selectedId,
|
|
8299
|
+
selfLogin: config2.board.assignee,
|
|
8300
|
+
panelWidth: issuesPanelWidth,
|
|
8301
|
+
stalenessConfig: config2.board.workflow?.staleness
|
|
8302
|
+
},
|
|
8303
|
+
row.key
|
|
8304
|
+
)) }) }),
|
|
8305
|
+
/* @__PURE__ */ jsx29(
|
|
8306
|
+
DetailPanel,
|
|
8307
|
+
{
|
|
8308
|
+
issue: selectedItem.issue,
|
|
8309
|
+
width: detailPanelWidth,
|
|
8310
|
+
isActive: false,
|
|
8311
|
+
issueRepo: selectedItem.repoName,
|
|
8312
|
+
fetchComments: handleFetchComments,
|
|
8313
|
+
commentsState: currentCommentsState
|
|
8314
|
+
}
|
|
8315
|
+
)
|
|
8316
|
+
] })
|
|
8317
|
+
) : null,
|
|
8327
8318
|
!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 !== "overlay:nudge" && ui.state.mode !== "overlay:triage" && ui.state.mode !== "focus" && ui.state.mode !== "zen" ? /* @__PURE__ */ jsx29(
|
|
8328
8319
|
PanelLayout,
|
|
8329
8320
|
{
|
|
@@ -9416,7 +9407,7 @@ async function resolveRef(ref, config2) {
|
|
|
9416
9407
|
}
|
|
9417
9408
|
}
|
|
9418
9409
|
var program = new Command();
|
|
9419
|
-
program.name("hog").description("Personal command deck \u2014 GitHub Projects dashboard with workflow orchestration").version("1.
|
|
9410
|
+
program.name("hog").description("Personal command deck \u2014 GitHub Projects dashboard with workflow orchestration").version("1.23.0").option("--json", "Force JSON output").option("--human", "Force human-readable output").hook("preAction", (thisCommand) => {
|
|
9420
9411
|
const opts = thisCommand.opts();
|
|
9421
9412
|
if (opts.json) setFormat("json");
|
|
9422
9413
|
if (opts.human) setFormat("human");
|