@colmbus72/yeehaw 0.4.2 → 0.6.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/claude-plugin/.claude-plugin/plugin.json +2 -1
- package/claude-plugin/hooks/hooks.json +41 -0
- package/claude-plugin/hooks/session-status.sh +13 -0
- package/claude-plugin/skills/yeehaw-development/SKILL.md +70 -0
- package/dist/app.js +228 -28
- package/dist/components/CritterHeader.d.ts +7 -0
- package/dist/components/CritterHeader.js +81 -0
- package/dist/components/HelpOverlay.js +4 -2
- package/dist/components/List.d.ts +10 -1
- package/dist/components/List.js +14 -5
- package/dist/components/Panel.js +27 -1
- package/dist/components/SplashScreen.js +1 -1
- package/dist/hooks/useSessions.js +2 -2
- package/dist/index.js +41 -1
- package/dist/lib/auth/index.d.ts +2 -0
- package/dist/lib/auth/index.js +3 -0
- package/dist/lib/auth/linear.d.ts +20 -0
- package/dist/lib/auth/linear.js +79 -0
- package/dist/lib/auth/storage.d.ts +12 -0
- package/dist/lib/auth/storage.js +53 -0
- package/dist/lib/config.d.ts +13 -1
- package/dist/lib/config.js +51 -0
- package/dist/lib/context.d.ts +10 -0
- package/dist/lib/context.js +63 -0
- package/dist/lib/critters.d.ts +61 -0
- package/dist/lib/critters.js +365 -0
- package/dist/lib/hooks.d.ts +20 -0
- package/dist/lib/hooks.js +91 -0
- package/dist/lib/hotkeys.d.ts +1 -1
- package/dist/lib/hotkeys.js +28 -20
- package/dist/lib/issues/github.d.ts +11 -0
- package/dist/lib/issues/github.js +154 -0
- package/dist/lib/issues/index.d.ts +14 -0
- package/dist/lib/issues/index.js +27 -0
- package/dist/lib/issues/linear.d.ts +24 -0
- package/dist/lib/issues/linear.js +345 -0
- package/dist/lib/issues/types.d.ts +82 -0
- package/dist/lib/issues/types.js +2 -0
- package/dist/lib/paths.d.ts +3 -0
- package/dist/lib/paths.js +3 -0
- package/dist/lib/signals.d.ts +30 -0
- package/dist/lib/signals.js +104 -0
- package/dist/lib/tmux.d.ts +9 -2
- package/dist/lib/tmux.js +114 -18
- package/dist/mcp-server.js +161 -1
- package/dist/types.d.ts +23 -2
- package/dist/views/BarnContext.d.ts +5 -2
- package/dist/views/BarnContext.js +202 -21
- package/dist/views/CritterDetailView.d.ts +10 -0
- package/dist/views/CritterDetailView.js +117 -0
- package/dist/views/CritterLogsView.d.ts +8 -0
- package/dist/views/CritterLogsView.js +100 -0
- package/dist/views/GlobalDashboard.d.ts +2 -2
- package/dist/views/GlobalDashboard.js +20 -18
- package/dist/views/IssuesView.d.ts +2 -1
- package/dist/views/IssuesView.js +661 -98
- package/dist/views/LivestockDetailView.d.ts +2 -1
- package/dist/views/LivestockDetailView.js +19 -8
- package/dist/views/ProjectContext.d.ts +2 -2
- package/dist/views/ProjectContext.js +68 -25
- package/package.json +5 -5
|
@@ -12,7 +12,7 @@ import { isLocalBarn } from '../lib/config.js';
|
|
|
12
12
|
function countSessionsForProject(projectName, windows) {
|
|
13
13
|
return windows.filter((w) => w.name.startsWith(projectName)).length;
|
|
14
14
|
}
|
|
15
|
-
export function GlobalDashboard({ projects, barns, windows, versionInfo, onSelectProject, onSelectBarn, onSelectWindow,
|
|
15
|
+
export function GlobalDashboard({ projects, barns, windows, versionInfo, onSelectProject, onSelectBarn, onSelectWindow, onNewClaudeForProject, onCreateProject, onCreateBarn, onSshToBarn, onInputModeChange, }) {
|
|
16
16
|
const [focusedPanel, setFocusedPanel] = useState('projects');
|
|
17
17
|
const [mode, setModeInternal] = useState('normal');
|
|
18
18
|
// Wrapper to notify parent when input mode changes
|
|
@@ -73,10 +73,6 @@ export function GlobalDashboard({ projects, barns, windows, versionInfo, onSelec
|
|
|
73
73
|
});
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
|
-
if (input === 'c') {
|
|
77
|
-
onNewClaude();
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
76
|
if (input === 'n') {
|
|
81
77
|
if (focusedPanel === 'projects') {
|
|
82
78
|
setMode('new-project-name');
|
|
@@ -93,10 +89,6 @@ export function GlobalDashboard({ projects, barns, windows, versionInfo, onSelec
|
|
|
93
89
|
return;
|
|
94
90
|
}
|
|
95
91
|
}
|
|
96
|
-
if (input === 's' && focusedPanel === 'barns') {
|
|
97
|
-
// SSH to selected barn - handled by list selection
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
92
|
// Number hotkeys 1-9 for quick session switching
|
|
101
93
|
const num = parseInt(input, 10);
|
|
102
94
|
if (num >= 1 && num <= 9) {
|
|
@@ -174,6 +166,7 @@ export function GlobalDashboard({ projects, barns, windows, versionInfo, onSelec
|
|
|
174
166
|
label: p.name,
|
|
175
167
|
status: sessionCount > 0 ? 'active' : 'inactive',
|
|
176
168
|
meta: sessionCount > 0 ? `${sessionCount} session${sessionCount > 1 ? 's' : ''}` : undefined,
|
|
169
|
+
actions: [{ key: 'c', label: 'claude' }],
|
|
177
170
|
};
|
|
178
171
|
});
|
|
179
172
|
// Parse window name to show clearer labels
|
|
@@ -202,11 +195,13 @@ export function GlobalDashboard({ projects, barns, windows, versionInfo, onSelec
|
|
|
202
195
|
// Use display numbers (1-9) instead of window index
|
|
203
196
|
const sessionItems = sessionWindows.map((w, i) => {
|
|
204
197
|
const { label, typeHint } = formatSessionLabel(w.name);
|
|
198
|
+
const statusInfo = getWindowStatus(w);
|
|
205
199
|
return {
|
|
206
200
|
id: String(w.index),
|
|
207
201
|
label: `[${i + 1}] ${label}`,
|
|
208
202
|
status: w.active ? 'active' : 'inactive',
|
|
209
|
-
meta: typeHint ? `${typeHint} · ${
|
|
203
|
+
meta: typeHint ? `${typeHint} · ${statusInfo.text}` : statusInfo.text,
|
|
204
|
+
sessionStatus: statusInfo.status,
|
|
210
205
|
};
|
|
211
206
|
});
|
|
212
207
|
const barnItems = barns.map((b) => ({
|
|
@@ -214,6 +209,7 @@ export function GlobalDashboard({ projects, barns, windows, versionInfo, onSelec
|
|
|
214
209
|
label: isLocalBarn(b) ? 'local' : b.name,
|
|
215
210
|
status: 'active',
|
|
216
211
|
meta: isLocalBarn(b) ? 'this machine' : `${b.user}@${b.host}`,
|
|
212
|
+
actions: [{ key: 's', label: 'shell' }],
|
|
217
213
|
}));
|
|
218
214
|
// New project modals
|
|
219
215
|
if (mode === 'new-project-name') {
|
|
@@ -260,23 +256,29 @@ export function GlobalDashboard({ projects, barns, windows, versionInfo, onSelec
|
|
|
260
256
|
if (mode === 'new-barn-key') {
|
|
261
257
|
return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Header, { text: "YEEHAW", versionInfo: versionInfo }), _jsxs(Box, { flexDirection: "column", padding: 2, children: [_jsxs(Text, { bold: true, color: "green", children: ["Add New Barn: ", newBarnName] }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { children: "SSH Key Path: " }), _jsx(PathInput, { value: newBarnKey, onChange: setNewBarnKey, onSubmit: handleBarnKeySubmit })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Tab: autocomplete, Enter: create barn, Esc: cancel" }) })] })] }));
|
|
262
258
|
}
|
|
263
|
-
// Panel-specific hints (page-level hotkeys like c are in BottomBar)
|
|
264
259
|
const projectHints = '[n] new';
|
|
265
|
-
const sessionHints = '
|
|
266
|
-
const barnHints = '[n] new
|
|
260
|
+
const sessionHints = '';
|
|
261
|
+
const barnHints = '[n] new';
|
|
267
262
|
return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Header, { text: "YEEHAW", versionInfo: versionInfo }), _jsxs(Box, { flexGrow: 1, marginY: 1, paddingX: 1, gap: 2, children: [_jsxs(Box, { flexDirection: "column", width: "40%", gap: 1, children: [_jsx(Panel, { title: "Projects", focused: focusedPanel === 'projects', hints: projectHints, children: projectItems.length > 0 ? (_jsx(List, { items: projectItems, focused: focusedPanel === 'projects', onSelect: (item) => {
|
|
268
263
|
const project = projects.find((p) => p.name === item.id);
|
|
269
264
|
if (project)
|
|
270
265
|
onSelectProject(project);
|
|
266
|
+
}, onAction: (item, actionKey) => {
|
|
267
|
+
if (actionKey === 'c') {
|
|
268
|
+
const project = projects.find((p) => p.name === item.id);
|
|
269
|
+
if (project)
|
|
270
|
+
onNewClaudeForProject(project);
|
|
271
|
+
}
|
|
271
272
|
} })) : (_jsx(Text, { dimColor: true, children: "No projects yet" })) }), _jsx(Box, { flexGrow: 1, width: "100%", children: _jsx(Panel, { title: "Barns", focused: focusedPanel === 'barns', width: "100%", hints: barnHints, children: barnItems.length > 0 ? (_jsx(Box, { flexDirection: "column", children: _jsx(List, { items: barnItems, focused: focusedPanel === 'barns', onSelect: (item) => {
|
|
272
273
|
const barn = barns.find((b) => b.name === item.id);
|
|
273
274
|
if (barn)
|
|
274
275
|
onSelectBarn(barn);
|
|
275
|
-
}, onAction: (item) => {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
276
|
+
}, onAction: (item, actionKey) => {
|
|
277
|
+
if (actionKey === 's') {
|
|
278
|
+
const barn = barns.find((b) => b.name === item.id);
|
|
279
|
+
if (barn)
|
|
280
|
+
onSshToBarn(barn);
|
|
281
|
+
}
|
|
280
282
|
} }) })) : (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "No barns configured" }), _jsx(Text, { dimColor: true, italic: true, children: "Barns are servers you manage" })] })) }) })] }), _jsx(Panel, { title: "Sessions", focused: focusedPanel === 'sessions', width: "60%", hints: sessionHints, children: sessionItems.length > 0 ? (_jsx(List, { items: sessionItems, focused: focusedPanel === 'sessions', onSelect: (item) => {
|
|
281
283
|
const window = sessionWindows.find((w) => String(w.index) === item.id);
|
|
282
284
|
if (window)
|
|
@@ -2,6 +2,7 @@ import type { Project } from '../types.js';
|
|
|
2
2
|
interface IssuesViewProps {
|
|
3
3
|
project: Project;
|
|
4
4
|
onBack: () => void;
|
|
5
|
+
onOpenClaude?: (workingDir: string, issueContext: string) => void;
|
|
5
6
|
}
|
|
6
|
-
export declare function IssuesView({ project, onBack }: IssuesViewProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function IssuesView({ project, onBack, onOpenClaude }: IssuesViewProps): import("react/jsx-runtime").JSX.Element | null;
|
|
7
8
|
export {};
|