@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.
Files changed (61) hide show
  1. package/claude-plugin/.claude-plugin/plugin.json +2 -1
  2. package/claude-plugin/hooks/hooks.json +41 -0
  3. package/claude-plugin/hooks/session-status.sh +13 -0
  4. package/claude-plugin/skills/yeehaw-development/SKILL.md +70 -0
  5. package/dist/app.js +228 -28
  6. package/dist/components/CritterHeader.d.ts +7 -0
  7. package/dist/components/CritterHeader.js +81 -0
  8. package/dist/components/HelpOverlay.js +4 -2
  9. package/dist/components/List.d.ts +10 -1
  10. package/dist/components/List.js +14 -5
  11. package/dist/components/Panel.js +27 -1
  12. package/dist/components/SplashScreen.js +1 -1
  13. package/dist/hooks/useSessions.js +2 -2
  14. package/dist/index.js +41 -1
  15. package/dist/lib/auth/index.d.ts +2 -0
  16. package/dist/lib/auth/index.js +3 -0
  17. package/dist/lib/auth/linear.d.ts +20 -0
  18. package/dist/lib/auth/linear.js +79 -0
  19. package/dist/lib/auth/storage.d.ts +12 -0
  20. package/dist/lib/auth/storage.js +53 -0
  21. package/dist/lib/config.d.ts +13 -1
  22. package/dist/lib/config.js +51 -0
  23. package/dist/lib/context.d.ts +10 -0
  24. package/dist/lib/context.js +63 -0
  25. package/dist/lib/critters.d.ts +61 -0
  26. package/dist/lib/critters.js +365 -0
  27. package/dist/lib/hooks.d.ts +20 -0
  28. package/dist/lib/hooks.js +91 -0
  29. package/dist/lib/hotkeys.d.ts +1 -1
  30. package/dist/lib/hotkeys.js +28 -20
  31. package/dist/lib/issues/github.d.ts +11 -0
  32. package/dist/lib/issues/github.js +154 -0
  33. package/dist/lib/issues/index.d.ts +14 -0
  34. package/dist/lib/issues/index.js +27 -0
  35. package/dist/lib/issues/linear.d.ts +24 -0
  36. package/dist/lib/issues/linear.js +345 -0
  37. package/dist/lib/issues/types.d.ts +82 -0
  38. package/dist/lib/issues/types.js +2 -0
  39. package/dist/lib/paths.d.ts +3 -0
  40. package/dist/lib/paths.js +3 -0
  41. package/dist/lib/signals.d.ts +30 -0
  42. package/dist/lib/signals.js +104 -0
  43. package/dist/lib/tmux.d.ts +9 -2
  44. package/dist/lib/tmux.js +114 -18
  45. package/dist/mcp-server.js +161 -1
  46. package/dist/types.d.ts +23 -2
  47. package/dist/views/BarnContext.d.ts +5 -2
  48. package/dist/views/BarnContext.js +202 -21
  49. package/dist/views/CritterDetailView.d.ts +10 -0
  50. package/dist/views/CritterDetailView.js +117 -0
  51. package/dist/views/CritterLogsView.d.ts +8 -0
  52. package/dist/views/CritterLogsView.js +100 -0
  53. package/dist/views/GlobalDashboard.d.ts +2 -2
  54. package/dist/views/GlobalDashboard.js +20 -18
  55. package/dist/views/IssuesView.d.ts +2 -1
  56. package/dist/views/IssuesView.js +661 -98
  57. package/dist/views/LivestockDetailView.d.ts +2 -1
  58. package/dist/views/LivestockDetailView.js +19 -8
  59. package/dist/views/ProjectContext.d.ts +2 -2
  60. package/dist/views/ProjectContext.js +68 -25
  61. 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, onNewClaude, onCreateProject, onCreateBarn, onSshToBarn, onInputModeChange, }) {
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} · ${getWindowStatus(w)}` : getWindowStatus(w),
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 = '1-9 switch';
266
- const barnHints = '[n] new [s] shell';
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
- // 's' key to SSH directly
277
- const barn = barns.find((b) => b.name === item.id);
278
- if (barn)
279
- onSshToBarn(barn);
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 {};