@ondrej-svec/hog 1.22.1 → 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 -127
- 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,44 +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
|
-
"sh",
|
|
4098
|
-
"-c",
|
|
4099
|
-
'printf "Issue: %s\\n\\nURL: %s\\n\\nNo Claude Code session active.\\nPress C to launch one.\\n" "$1" "$2"; read _',
|
|
4100
|
-
"--",
|
|
4101
|
-
info.title,
|
|
4102
|
-
info.url
|
|
4103
|
-
],
|
|
4104
|
-
{
|
|
4105
|
-
encoding: "utf-8",
|
|
4106
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
4107
|
-
}
|
|
4108
|
-
);
|
|
4109
|
-
return paneId.trim() || null;
|
|
4110
|
-
} catch {
|
|
4111
|
-
return null;
|
|
4112
|
-
}
|
|
4113
|
-
}
|
|
4114
|
-
function killPane(paneId) {
|
|
4115
|
-
try {
|
|
4116
|
-
execFileSync3("tmux", ["kill-pane", "-t", paneId], {
|
|
4117
|
-
stdio: "ignore"
|
|
4118
|
-
});
|
|
4119
|
-
} catch {
|
|
4120
|
-
}
|
|
4121
|
-
}
|
|
4122
4113
|
var init_tmux_pane = __esm({
|
|
4123
4114
|
"src/board/tmux-pane.ts"() {
|
|
4124
4115
|
"use strict";
|
|
@@ -4127,32 +4118,16 @@ var init_tmux_pane = __esm({
|
|
|
4127
4118
|
|
|
4128
4119
|
// src/board/hooks/use-zen-mode.ts
|
|
4129
4120
|
import { useCallback as useCallback13, useEffect as useEffect5, useRef as useRef11, useState as useState7 } from "react";
|
|
4130
|
-
function
|
|
4121
|
+
function issueNumberFromId(selectedId) {
|
|
4131
4122
|
if (!selectedId?.startsWith("gh:")) return null;
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
return { issue, repoName: rd.repo.name };
|
|
4136
|
-
}
|
|
4137
|
-
}
|
|
4138
|
-
return null;
|
|
4139
|
-
}
|
|
4140
|
-
function cleanupPane(paneId, isAgent) {
|
|
4141
|
-
if (isAgent) {
|
|
4142
|
-
breakPane(paneId);
|
|
4143
|
-
} else {
|
|
4144
|
-
killPane(paneId);
|
|
4145
|
-
}
|
|
4123
|
+
const parts = selectedId.split(":");
|
|
4124
|
+
const num = Number(parts[2]);
|
|
4125
|
+
return Number.isNaN(num) ? null : num;
|
|
4146
4126
|
}
|
|
4147
|
-
function
|
|
4148
|
-
const winName = agentWindowName(
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
const paneId2 = joinAgentPane(winName, ZEN_PANE_WIDTH_PERCENT);
|
|
4152
|
-
return paneId2 ? { paneId: paneId2, isAgent: true } : null;
|
|
4153
|
-
}
|
|
4154
|
-
const paneId = splitWithInfo({ title: issue.title, url: issue.url }, ZEN_PANE_WIDTH_PERCENT);
|
|
4155
|
-
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);
|
|
4156
4131
|
}
|
|
4157
4132
|
function useZenMode({
|
|
4158
4133
|
ui,
|
|
@@ -4162,21 +4137,19 @@ function useZenMode({
|
|
|
4162
4137
|
selectedId
|
|
4163
4138
|
}) {
|
|
4164
4139
|
const [zenPaneId, setZenPaneId] = useState7(null);
|
|
4165
|
-
const
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
});
|
|
4170
|
-
paneRef.current = { id: zenPaneId, isAgent: zenIsAgentPane };
|
|
4171
|
-
const exitZen = useCallback13(() => {
|
|
4172
|
-
const { id, isAgent } = paneRef.current;
|
|
4140
|
+
const paneRef = useRef11(null);
|
|
4141
|
+
paneRef.current = zenPaneId;
|
|
4142
|
+
const cleanupCurrentPane = useCallback13(() => {
|
|
4143
|
+
const id = paneRef.current;
|
|
4173
4144
|
if (id) {
|
|
4174
|
-
|
|
4145
|
+
breakPane(id);
|
|
4175
4146
|
setZenPaneId(null);
|
|
4176
|
-
setZenIsAgentPane(false);
|
|
4177
4147
|
}
|
|
4148
|
+
}, []);
|
|
4149
|
+
const exitZen = useCallback13(() => {
|
|
4150
|
+
cleanupCurrentPane();
|
|
4178
4151
|
ui.exitZen();
|
|
4179
|
-
}, [ui]);
|
|
4152
|
+
}, [ui, cleanupCurrentPane]);
|
|
4180
4153
|
const handleToggleZen = useCallback13(() => {
|
|
4181
4154
|
if (ui.state.mode === "zen") {
|
|
4182
4155
|
exitZen();
|
|
@@ -4190,70 +4163,54 @@ function useZenMode({
|
|
|
4190
4163
|
toast.error("Terminal too narrow for Zen mode");
|
|
4191
4164
|
return;
|
|
4192
4165
|
}
|
|
4193
|
-
const
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
return;
|
|
4166
|
+
const issueNum = issueNumberFromId(selectedId);
|
|
4167
|
+
if (issueNum) {
|
|
4168
|
+
const paneId = tryJoinAgent(issueNum);
|
|
4169
|
+
if (paneId) setZenPaneId(paneId);
|
|
4198
4170
|
}
|
|
4199
|
-
setZenPaneId(result.paneId);
|
|
4200
|
-
setZenIsAgentPane(result.isAgent);
|
|
4201
4171
|
ui.enterZen();
|
|
4202
|
-
}, [ui, toast, termCols, exitZen,
|
|
4172
|
+
}, [ui, toast, termCols, exitZen, selectedId]);
|
|
4203
4173
|
const swapToAgent = useCallback13(
|
|
4204
4174
|
(issueNumber) => {
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
cleanupPane(id, isAgent);
|
|
4175
|
+
if (ui.state.mode !== "zen") return;
|
|
4176
|
+
cleanupCurrentPane();
|
|
4208
4177
|
setTimeout(() => {
|
|
4209
|
-
const
|
|
4210
|
-
if (
|
|
4211
|
-
const newPaneId = joinAgentPane(winName, ZEN_PANE_WIDTH_PERCENT);
|
|
4212
|
-
setZenPaneId(newPaneId);
|
|
4213
|
-
setZenIsAgentPane(true);
|
|
4214
|
-
}
|
|
4178
|
+
const paneId = tryJoinAgent(issueNumber);
|
|
4179
|
+
if (paneId) setZenPaneId(paneId);
|
|
4215
4180
|
}, 500);
|
|
4216
4181
|
},
|
|
4217
|
-
[ui.state.mode]
|
|
4182
|
+
[ui.state.mode, cleanupCurrentPane]
|
|
4218
4183
|
);
|
|
4219
4184
|
const prevSelectedRef = useRef11(null);
|
|
4220
4185
|
useEffect5(() => {
|
|
4221
|
-
if (ui.state.mode !== "zen"
|
|
4186
|
+
if (ui.state.mode !== "zen") {
|
|
4222
4187
|
prevSelectedRef.current = selectedId;
|
|
4223
4188
|
return;
|
|
4224
4189
|
}
|
|
4225
4190
|
if (selectedId === prevSelectedRef.current) return;
|
|
4226
4191
|
prevSelectedRef.current = selectedId;
|
|
4227
4192
|
const timer = setTimeout(() => {
|
|
4228
|
-
const
|
|
4229
|
-
if (
|
|
4230
|
-
|
|
4231
|
-
if (!found) return;
|
|
4232
|
-
cleanupPane(id, isAgent);
|
|
4233
|
-
const result = openOrSplitPane(found.issue);
|
|
4234
|
-
if (!result) {
|
|
4235
|
-
setZenPaneId(null);
|
|
4236
|
-
setZenIsAgentPane(false);
|
|
4237
|
-
ui.exitZen();
|
|
4238
|
-
toast.error("Zen pane lost \u2014 exiting zen mode");
|
|
4239
|
-
return;
|
|
4193
|
+
const currentId = paneRef.current;
|
|
4194
|
+
if (currentId) {
|
|
4195
|
+
breakPane(currentId);
|
|
4240
4196
|
}
|
|
4241
|
-
|
|
4242
|
-
|
|
4197
|
+
const issueNum = issueNumberFromId(selectedId);
|
|
4198
|
+
const newPaneId = issueNum ? tryJoinAgent(issueNum) : null;
|
|
4199
|
+
setZenPaneId(newPaneId);
|
|
4243
4200
|
}, CURSOR_FOLLOW_DEBOUNCE_MS);
|
|
4244
4201
|
return () => clearTimeout(timer);
|
|
4245
|
-
}, [ui.state.mode,
|
|
4202
|
+
}, [ui.state.mode, selectedId, repos]);
|
|
4246
4203
|
useEffect5(() => {
|
|
4247
4204
|
if (ui.state.mode !== "zen" || !zenPaneId) return;
|
|
4248
4205
|
const interval = setInterval(() => {
|
|
4249
4206
|
if (!isPaneAlive(zenPaneId)) {
|
|
4250
|
-
|
|
4251
|
-
toast.info("
|
|
4207
|
+
setZenPaneId(null);
|
|
4208
|
+
toast.info("Agent pane closed");
|
|
4252
4209
|
}
|
|
4253
4210
|
}, DEAD_PANE_CHECK_MS);
|
|
4254
4211
|
return () => clearInterval(interval);
|
|
4255
|
-
}, [ui.state.mode, zenPaneId,
|
|
4256
|
-
return { zenPaneId,
|
|
4212
|
+
}, [ui.state.mode, zenPaneId, toast]);
|
|
4213
|
+
return { zenPaneId, handleToggleZen, swapToAgent };
|
|
4257
4214
|
}
|
|
4258
4215
|
var ZEN_PANE_WIDTH_PERCENT, ZEN_MIN_COLS, CURSOR_FOLLOW_DEBOUNCE_MS, DEAD_PANE_CHECK_MS;
|
|
4259
4216
|
var init_use_zen_mode = __esm({
|
|
@@ -4262,7 +4219,7 @@ var init_use_zen_mode = __esm({
|
|
|
4262
4219
|
init_tmux_pane();
|
|
4263
4220
|
ZEN_PANE_WIDTH_PERCENT = 65;
|
|
4264
4221
|
ZEN_MIN_COLS = 100;
|
|
4265
|
-
CURSOR_FOLLOW_DEBOUNCE_MS =
|
|
4222
|
+
CURSOR_FOLLOW_DEBOUNCE_MS = 200;
|
|
4266
4223
|
DEAD_PANE_CHECK_MS = 2e3;
|
|
4267
4224
|
}
|
|
4268
4225
|
});
|
|
@@ -4609,7 +4566,10 @@ function HintBar({
|
|
|
4609
4566
|
if (uiMode === "zen") {
|
|
4610
4567
|
return /* @__PURE__ */ jsxs6(Box6, { children: [
|
|
4611
4568
|
/* @__PURE__ */ jsx6(Text6, { color: "green", bold: true, children: "[ZEN]" }),
|
|
4612
|
-
/* @__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
|
+
] })
|
|
4613
4573
|
] });
|
|
4614
4574
|
}
|
|
4615
4575
|
if (uiMode === "focus") {
|
|
@@ -8315,17 +8275,46 @@ function Dashboard({ config: config2, options, activeProfile }) {
|
|
|
8315
8275
|
commentsState: currentCommentsState
|
|
8316
8276
|
}
|
|
8317
8277
|
) : null,
|
|
8318
|
-
ui.state.mode === "zen" ?
|
|
8319
|
-
|
|
8320
|
-
{
|
|
8321
|
-
|
|
8322
|
-
|
|
8323
|
-
|
|
8324
|
-
|
|
8325
|
-
|
|
8326
|
-
|
|
8327
|
-
|
|
8328
|
-
|
|
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,
|
|
8329
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(
|
|
8330
8319
|
PanelLayout,
|
|
8331
8320
|
{
|
|
@@ -9418,7 +9407,7 @@ async function resolveRef(ref, config2) {
|
|
|
9418
9407
|
}
|
|
9419
9408
|
}
|
|
9420
9409
|
var program = new Command();
|
|
9421
|
-
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) => {
|
|
9422
9411
|
const opts = thisCommand.opts();
|
|
9423
9412
|
if (opts.json) setFormat("json");
|
|
9424
9413
|
if (opts.human) setFormat("human");
|