@kud/gh-cockpit 0.1.0 → 0.1.1
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 +185 -114
- package/dist/extensions/index.js +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +3 -2
- package/package.json +3 -3
- package/dist/{chunk-A3NXVFEI.js → chunk-TEWCRLXY.js} +22 -22
package/README.md
CHANGED
|
@@ -1,162 +1,233 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
🛫
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# Cockpit
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
── acme/api-gateway ─────
|
|
12
|
-
◆ ← #1495 support statementPeriodIds… 6d
|
|
13
|
-
── acme/event-bus ───────
|
|
14
|
-
· #290 delete the legacy path 14h
|
|
12
|
+
**A configurable GitHub cockpit for the terminal — your PRs, reviews and issues in one Ink TUI, grouped by whose move it is.**
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
── acme/monorepo ────────
|
|
18
|
-
~ #10 add internalNotes field 1w
|
|
19
|
-
── acme/api-gateway ─────
|
|
20
|
-
✗ ← #1496 point history at the route 2d
|
|
21
|
-
! #1449 guard null ids 6w
|
|
22
|
-
```
|
|
14
|
+
[Features](#-features) • [Quick Start](#-quick-start) • [Build a CLI](#️-build-your-own-cli) • [API Reference](#-api-reference)
|
|
23
15
|
|
|
24
|
-
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
## 🌟 Features
|
|
19
|
+
|
|
20
|
+
- 🎯 **Whose-move bands** — every tab splits into `Your move` and `Their move`, so the two rows you can act on stop hiding among the eighteen you can't
|
|
21
|
+
- 🧭 **Standing, not guesswork** — the same `✗` is your afternoon on a PR you wrote and the author's on one you were asked to review; the band knows which
|
|
22
|
+
- 🔍 **`--here` scoping** — resolves the repo from your git remote and scopes every search server-side, so other repos are never fetched at all
|
|
23
|
+
- 🎛️ **Pattern filtering** — `--include acme/*,me/acme-*` and `--exclude`, replacing any built-in notion of which repos are "yours"
|
|
24
|
+
- 🔌 **Bring your own CI** — GitHub Actions logs are built in; register a drill-in for anything else, or let it open in a browser
|
|
25
|
+
- ♿ **Readable without colour** — every state carries its own glyph, so the list survives being piped, logged, or read by someone who can't separate green from orange
|
|
26
|
+
- 🪶 **No opinions baked in** — repo ranking, checkout locations and cache lifetime are all supplied by the host; the defaults are empty on purpose
|
|
27
|
+
|
|
28
|
+
## 🚀 Quick Start
|
|
25
29
|
|
|
26
30
|
```sh
|
|
27
31
|
npm install @kud/gh-cockpit
|
|
28
32
|
```
|
|
29
33
|
|
|
30
|
-
It is a
|
|
31
|
-
|
|
32
|
-
## Whose move is it
|
|
34
|
+
It is a library, not a CLI — there is no `bin`, because which searches become tabs and which repos rank first are not portable decisions. You write a short entry point; see [Build your own CLI](#️-build-your-own-cli) for a complete one.
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
What it renders:
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
| `✗` CI failing · `!` conflict · `±` changes requested | **you** | them | them |
|
|
39
|
-
| `·` awaiting review · `*` checks running | them | **you** | them |
|
|
40
|
-
| `✓` approved | **you** | **you** | them |
|
|
41
|
-
| `◆` open threads | **you** | **you** | **you** |
|
|
42
|
-
| `~` draft | them | them | them |
|
|
38
|
+
```console
|
|
39
|
+
$ cockpit
|
|
43
40
|
|
|
44
|
-
|
|
41
|
+
🚀 Cockpit 29 items · @you updated 2m ago
|
|
42
|
+
Mine (7) Review (20) Incoming (4) Issues (3) Done (13)
|
|
43
|
+
───────────
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
> Every state has its own glyph, never a colour alone. Colour reinforces; it never carries meaning by itself.
|
|
45
|
+
» Your move (2)
|
|
48
46
|
|
|
49
|
-
|
|
47
|
+
── acme/api-gateway ─────
|
|
48
|
+
◆ ← #1495 support statementPeriodIds in the report 6d
|
|
49
|
+
── acme/event-bus ───────
|
|
50
|
+
· #290 delete the legacy serving path 14h
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
import { defineCockpit } from "@kud/gh-cockpit"
|
|
53
|
-
import { delegateExtension } from "@kud/gh-cockpit/extensions"
|
|
52
|
+
» Their move (18)
|
|
54
53
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
help: "your PRs, draft and open",
|
|
61
|
-
searches: ["is:open author:@me"],
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
label: "Review",
|
|
65
|
-
help: "theirs — asked of you, or you reviewed",
|
|
66
|
-
searches: [
|
|
67
|
-
{ q: "is:open review-requested:@me", standing: "queued" },
|
|
68
|
-
{
|
|
69
|
-
q: "is:open reviewed-by:@me -author:@me -review-requested:@me",
|
|
70
|
-
standing: "spoken",
|
|
71
|
-
},
|
|
72
|
-
],
|
|
73
|
-
},
|
|
74
|
-
],
|
|
75
|
-
extensions: [delegateExtension],
|
|
76
|
-
})
|
|
54
|
+
── acme/monorepo ────────
|
|
55
|
+
~ #10 add internalNotes to Contract 1w
|
|
56
|
+
── acme/api-gateway ─────
|
|
57
|
+
✗ ← #1496 point history at the generic route 2d
|
|
58
|
+
! #1449 guard null ids before per-id fetches 6w
|
|
77
59
|
```
|
|
78
60
|
|
|
79
|
-
|
|
61
|
+
## 🛠️ Build your own CLI
|
|
80
62
|
|
|
81
|
-
|
|
63
|
+
The package has no `bin`, so this is the file you write. It is short — fetch, assemble, render — and everything opinionated lives in it rather than in the package.
|
|
82
64
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
65
|
+
```tsx
|
|
66
|
+
#!/usr/bin/env node
|
|
67
|
+
import { $ } from "zx"
|
|
68
|
+
import React from "react"
|
|
69
|
+
import { render } from "ink"
|
|
70
|
+
import {
|
|
71
|
+
App,
|
|
72
|
+
buildInboxQuery,
|
|
73
|
+
configureInbox,
|
|
74
|
+
detailFor,
|
|
75
|
+
layoutGHItems,
|
|
76
|
+
signalPath,
|
|
77
|
+
toGHItem,
|
|
78
|
+
withRetry,
|
|
79
|
+
type Section,
|
|
80
|
+
} from "@kud/gh-cockpit"
|
|
81
|
+
|
|
82
|
+
$.verbose = false
|
|
83
|
+
|
|
84
|
+
// Everything the library refuses to assume. Call once, before rendering.
|
|
85
|
+
configureInbox({
|
|
86
|
+
repoPriority: ["acme/monorepo", "acme/", "me/"],
|
|
87
|
+
checkoutDir: `${process.env.HOME}/src`,
|
|
88
|
+
cacheNamespace: "my-cockpit",
|
|
89
|
+
cacheTtlMs: 20 * 60_000,
|
|
90
|
+
})
|
|
88
91
|
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
// One GraphQL round trip for every tab. `withRetry` matters: GitHub returns 502
|
|
93
|
+
// under load, and a 502 is the server declining to compute an answer, not an answer.
|
|
94
|
+
const fetchCockpit = async (): Promise<{ sections: Section[]; login: string }> => {
|
|
95
|
+
const result = await withRetry(() =>
|
|
96
|
+
$`gh api graphql -f query=${buildInboxQuery({})}`.quiet(),
|
|
97
|
+
)
|
|
98
|
+
const data = JSON.parse(result.stdout).data
|
|
99
|
+
|
|
100
|
+
const rows = (nodes: any[], standing?: "authored" | "queued" | "spoken") =>
|
|
101
|
+
(nodes ?? []).map((n) => ({ ...toGHItem(n), ...(standing ? { standing } : {}) }))
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
login: data.viewer.login,
|
|
105
|
+
sections: [
|
|
106
|
+
{
|
|
107
|
+
id: "mine",
|
|
108
|
+
label: "Mine",
|
|
109
|
+
items: layoutGHItems(rows(data.myPRs.nodes, "authored"), "mine"),
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
// Two searches, one tab. `standing` is stamped per search because nothing
|
|
113
|
+
// on a row can tell them apart afterwards.
|
|
114
|
+
id: "review",
|
|
115
|
+
label: "Review",
|
|
116
|
+
items: layoutGHItems(
|
|
117
|
+
[
|
|
118
|
+
...rows(data.reviewRequests.nodes, "queued"),
|
|
119
|
+
...rows(data.reviewed.nodes, "spoken"),
|
|
120
|
+
],
|
|
121
|
+
"review",
|
|
122
|
+
),
|
|
123
|
+
},
|
|
124
|
+
{ id: "done", label: "Done", items: layoutGHItems(rows(data.recentlyDone.nodes), "done") },
|
|
125
|
+
].filter((s) => s.items.some((i) => i.kind !== "repo-header")),
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
render(
|
|
130
|
+
<App
|
|
131
|
+
fetcher={fetchCockpit}
|
|
132
|
+
cacheKey="cockpit"
|
|
133
|
+
title="cockpit"
|
|
134
|
+
detailFor={detailFor}
|
|
135
|
+
tabHelp={[
|
|
136
|
+
["Mine", "your PRs, draft and open"],
|
|
137
|
+
["Review", "theirs — asked of you, or you reviewed"],
|
|
138
|
+
["Done", "your PRs closed < 14d"],
|
|
139
|
+
]}
|
|
140
|
+
emptyHint="Nothing open across your repos."
|
|
141
|
+
watchPath={signalPath()}
|
|
142
|
+
watchDebounceMs={2_000}
|
|
143
|
+
/>,
|
|
144
|
+
{ alternateScreen: true },
|
|
145
|
+
)
|
|
91
146
|
```
|
|
92
147
|
|
|
93
|
-
|
|
148
|
+
Point a `bin` at it in your own `package.json` and it is a command.
|
|
94
149
|
|
|
95
|
-
|
|
96
|
-
gh-cockpit --exclude 'acme/legacy'
|
|
97
|
-
```
|
|
150
|
+
### Refreshing without polling
|
|
98
151
|
|
|
99
|
-
|
|
152
|
+
`watchPath` is a file the cockpit watches; writing a byte to it makes every open cockpit refetch, debounced. Have whatever mutates GitHub on your behalf — a merge script, an editor hook — write to `signalPath()`.
|
|
100
153
|
|
|
101
|
-
|
|
102
|
-
gh-cockpit --here
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
`--here` is not a filter. It resolves the repo from your git remote — `upstream` if present, else `origin` — and scopes every search **server-side** with `repo:owner/name`, so other repos are never fetched at all. On a fork that matters: `origin` is your copy and `upstream` is where the PRs actually live.
|
|
154
|
+
A poller is wrong twice over: it spends quota on the long stretches where nothing changed, and it is still up to a full interval late when something did. The filesystem is the whole broker — no daemon, no socket, and the fan-out is free.
|
|
106
155
|
|
|
107
|
-
|
|
156
|
+
> [!IMPORTANT]
|
|
157
|
+
> Write a byte rather than `touch`ing. At second-granularity mtime with no size change, two touches inside the same second are indistinguishable and some watch backends coalesce them away.
|
|
108
158
|
|
|
109
|
-
|
|
159
|
+
## 📖 API Reference
|
|
110
160
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
161
|
+
| Export | Purpose |
|
|
162
|
+
| ---------------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
163
|
+
| `defineCockpit(config)` | Types your own config object. A convenience for hosts — nothing internal reads it |
|
|
164
|
+
| `configureInbox(config)` | Host opinions: `repoPriority`, `profiles`, `checkoutDir`, `cacheNamespace`, `cacheTtlMs` |
|
|
165
|
+
| `parseArgs(argv)` | Parses `--here`, `--include`, `--exclude` and a positional filter name. You decide what they mean |
|
|
166
|
+
| `registerCheckDrills(drills)` | Where a CI check drills in; unregistered checks open in a browser |
|
|
167
|
+
| `detailFor(ctx)` | The drill-in view for a row — `PrView` or `IssueView` |
|
|
168
|
+
| `PrView` · `IssueView` | The drill-in views themselves, if you want to wrap them |
|
|
169
|
+
| `withRetry(fn)` | Retries transient `50x` responses; GitHub returns them under load |
|
|
170
|
+
| `toGHItem(node)` · `computeHealth(node)` | GraphQL node → row, and the health token behind each glyph |
|
|
117
171
|
|
|
118
|
-
|
|
172
|
+
### Whose move is it
|
|
119
173
|
|
|
120
|
-
|
|
174
|
+
| | `authored`<br>your PR | `queued`<br>asked of you | `spoken`<br>you reviewed |
|
|
175
|
+
| ----------------------------------------------------- | --------------------- | ------------------------ | ------------------------ |
|
|
176
|
+
| `✗` CI failing · `!` conflict · `±` changes requested | **you** | them | them |
|
|
177
|
+
| `·` awaiting review · `*` checks running | them | **you** | them |
|
|
178
|
+
| `✓` approved | **you** | **you** | them |
|
|
179
|
+
| `◆` open threads | **you** | **you** | **you** |
|
|
180
|
+
| `~` draft | them | them | them |
|
|
121
181
|
|
|
122
|
-
|
|
182
|
+
`standing` is declared per search rather than inferred, because nothing on a row records it: a PR awaiting review and one you already reviewed are the same PR to GitHub's API, and opposite things to you.
|
|
123
183
|
|
|
124
|
-
|
|
125
|
-
import { registerCheckDrills } from "@kud/gh-cockpit"
|
|
184
|
+
### Filtering
|
|
126
185
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
match: (url) => url.includes("ci.example"),
|
|
130
|
-
render: ({ url, name, onBack }) => <MyBuildView url={url} name={name} onBack={onBack} />,
|
|
131
|
-
},
|
|
132
|
-
])
|
|
186
|
+
```sh
|
|
187
|
+
cockpit --include 'acme/*,me/acme-*'
|
|
133
188
|
```
|
|
134
189
|
|
|
135
|
-
|
|
190
|
+
`*` matches within one path segment and never across the `/`, so `acme/*` cannot reach another owner and `acme` will not claim `acmecorp`. A bare owner is sugar for all its repos. `--exclude` is applied after `--include` and wins, so you can take a whole org and drop one repo without listing the rest.
|
|
191
|
+
|
|
192
|
+
## 🔧 Development
|
|
136
193
|
|
|
137
|
-
|
|
194
|
+
```sh
|
|
195
|
+
git clone https://github.com/kud/gh.git
|
|
196
|
+
```
|
|
138
197
|
|
|
139
|
-
```
|
|
140
|
-
|
|
198
|
+
```sh
|
|
199
|
+
cd gh && npm install
|
|
200
|
+
```
|
|
141
201
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
checkoutDir: `${process.env.HOME}/src`,
|
|
145
|
-
cacheNamespace: "my-cockpit",
|
|
146
|
-
cacheTtlMs: 20 * 60_000,
|
|
147
|
-
})
|
|
202
|
+
```sh
|
|
203
|
+
npm run build --workspace @kud/gh-cockpit
|
|
148
204
|
```
|
|
149
205
|
|
|
150
|
-
|
|
151
|
-
|
|
206
|
+
| Script | Does |
|
|
207
|
+
| ------------------- | ---------------------------------- |
|
|
208
|
+
| `npm run build` | Compile `src/` → `dist/` with tsup |
|
|
209
|
+
| `npm run dev` | Same, in watch mode |
|
|
210
|
+
| `npm run typecheck` | `tsc --noEmit` |
|
|
211
|
+
| `npm test` | Vitest |
|
|
152
212
|
|
|
153
|
-
|
|
213
|
+
```
|
|
214
|
+
src/
|
|
215
|
+
config.ts defineCockpit and the config types
|
|
216
|
+
args.ts --here / --include / --exclude parsing
|
|
217
|
+
lib.ts shared layer, re-exports @kud/gh-ink
|
|
218
|
+
views/ PrView, IssueView, and the drill-in views
|
|
219
|
+
extensions/ opt-in extensions, exported separately
|
|
220
|
+
```
|
|
154
221
|
|
|
155
|
-
|
|
222
|
+
## 🏗️ Tech Stack
|
|
156
223
|
|
|
157
|
-
|
|
158
|
-
|
|
224
|
+
| | |
|
|
225
|
+
| -------------------------------------------------------- | -------------------------------------------------- |
|
|
226
|
+
| [@kud/gh](https://www.npmjs.com/package/@kud/gh) | Surface-agnostic core: queries, health computation |
|
|
227
|
+
| [@kud/gh-ink](https://www.npmjs.com/package/@kud/gh-ink) | Ink components, whose-move banding, layout |
|
|
228
|
+
| [@kud/ink-ui](https://www.npmjs.com/package/@kud/ink-ui) | Terminal UI primitives |
|
|
229
|
+
| [zx](https://www.npmjs.com/package/zx) | Shelling out to `gh` |
|
|
159
230
|
|
|
160
|
-
|
|
231
|
+
---
|
|
161
232
|
|
|
162
|
-
MIT ©
|
|
233
|
+
MIT © [kud](https://github.com/kud) — Made with ❤️
|
package/dist/extensions/index.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -98,6 +98,13 @@ declare const hasPatterns: (f: RepoFilter) => boolean;
|
|
|
98
98
|
|
|
99
99
|
declare const detailFor: (ctx: DetailContext) => React.JSX.Element;
|
|
100
100
|
|
|
101
|
+
declare const DrillView: ({ title, subtitle, hints, children, }: {
|
|
102
|
+
title: string;
|
|
103
|
+
subtitle?: string;
|
|
104
|
+
hints: [string, string][];
|
|
105
|
+
children: React.ReactNode;
|
|
106
|
+
}) => React.JSX.Element;
|
|
107
|
+
|
|
101
108
|
type Tab = "health" | "conversation";
|
|
102
109
|
declare const PrView: ({ item, login, onBack, defaultTab, onRefresh, onRemove, onMerged, }: {
|
|
103
110
|
item: GHItem;
|
|
@@ -121,4 +128,4 @@ declare const IssueView: ({ item, login, onBack, }: {
|
|
|
121
128
|
onBack: () => void;
|
|
122
129
|
}) => React.JSX.Element;
|
|
123
130
|
|
|
124
|
-
export { type CheckDrill, type CheckDrillContext, type CockpitArgs, type CockpitConfig, type CockpitItem, IssueView, PrView, type TabSearch, type TabSpec, checkDrillFor, computeHealth, defineCockpit, detailFor, hasPatterns, parseArgs, registerCheckDrills, signalPath, toGHItem, withRetry };
|
|
131
|
+
export { type CheckDrill, type CheckDrillContext, type CockpitArgs, type CockpitConfig, type CockpitItem, DrillView, IssueView, PrView, type TabSearch, type TabSpec, checkDrillFor, computeHealth, defineCockpit, detailFor, hasPatterns, parseArgs, registerCheckDrills, signalPath, toGHItem, withRetry };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { __export, withRetry, toGHItem, signalPath, computeHealth, buildInboxQuery, lib_exports, AiLauncher, seedPromptFor, CopyPromptNotice,
|
|
2
|
-
export { buildInboxQuery, computeHealth, signalPath, toGHItem, withRetry } from './chunk-
|
|
1
|
+
import { __export, withRetry, toGHItem, signalPath, computeHealth, buildInboxQuery, DrillView, lib_exports, AiLauncher, seedPromptFor, CopyPromptNotice, __reExport } from './chunk-TEWCRLXY.js';
|
|
2
|
+
export { DrillView, buildInboxQuery, computeHealth, signalPath, toGHItem, withRetry } from './chunk-TEWCRLXY.js';
|
|
3
3
|
import { parsePatterns, HealthPanel, CommentsPanel, inboxConfig } from '@kud/gh-ink';
|
|
4
4
|
import { $ } from 'zx';
|
|
5
5
|
import { useState, useEffect } from 'react';
|
|
@@ -14,6 +14,7 @@ import { join } from 'path';
|
|
|
14
14
|
// src/index.ts
|
|
15
15
|
var index_exports = {};
|
|
16
16
|
__export(index_exports, {
|
|
17
|
+
DrillView: () => DrillView,
|
|
17
18
|
IssueView: () => IssueView,
|
|
18
19
|
PrView: () => PrView,
|
|
19
20
|
buildInboxQuery: () => buildInboxQuery,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kud/gh-cockpit",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "A configurable GitHub cockpit for the terminal
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "A configurable GitHub cockpit for the terminal — your PRs, reviews and issues in one Ink TUI, grouped by whose move it is.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@kud/gh": "0.5.1",
|
|
57
|
-
"@kud/gh-ink": "0.
|
|
57
|
+
"@kud/gh-ink": "0.22.0",
|
|
58
58
|
"@kud/ink-ui": "0.14.0",
|
|
59
59
|
"zx": "8.8.5"
|
|
60
60
|
},
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { useWindowSize, Box, Text, useInput } from 'ink';
|
|
2
|
+
import { Panel, colors, FooterHints, useListCursor } from '@kud/ink-ui';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
1
4
|
import * as gh_ink_star from '@kud/gh-ink';
|
|
2
5
|
import { relativeTime, inboxConfig } from '@kud/gh-ink';
|
|
3
6
|
import { mkdirSync } from 'fs';
|
|
@@ -5,9 +8,6 @@ import { homedir } from 'os';
|
|
|
5
8
|
import { join } from 'path';
|
|
6
9
|
import { buildInboxQuery, computeHealth as computeHealth$1, latestChecks, isPendingCheck, isFailCheck, isPassCheck } from '@kud/gh';
|
|
7
10
|
export { buildInboxQuery } from '@kud/gh';
|
|
8
|
-
import { useWindowSize, Box, Text, useInput } from 'ink';
|
|
9
|
-
import { Panel, colors, FooterHints, useListCursor } from '@kud/ink-ui';
|
|
10
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
11
11
|
import { $ } from 'zx';
|
|
12
12
|
import { useRef, useEffect, useState } from 'react';
|
|
13
13
|
|
|
@@ -28,6 +28,25 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
28
28
|
return to;
|
|
29
29
|
};
|
|
30
30
|
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
31
|
+
var DrillView = ({
|
|
32
|
+
title,
|
|
33
|
+
subtitle,
|
|
34
|
+
hints,
|
|
35
|
+
children
|
|
36
|
+
}) => {
|
|
37
|
+
const { rows } = useWindowSize();
|
|
38
|
+
return /* @__PURE__ */ jsx(Panel, { children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", height: rows - 2, paddingX: 1, children: [
|
|
39
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
40
|
+
/* @__PURE__ */ jsx(Text, { color: colors.accent, bold: true, children: title }),
|
|
41
|
+
subtitle ? /* @__PURE__ */ jsxs(Box, { marginTop: 1, children: [
|
|
42
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Title: " }),
|
|
43
|
+
/* @__PURE__ */ jsx(Text, { children: subtitle })
|
|
44
|
+
] }) : null
|
|
45
|
+
] }),
|
|
46
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", flexGrow: 1, children }),
|
|
47
|
+
/* @__PURE__ */ jsx(FooterHints, { hints })
|
|
48
|
+
] }) });
|
|
49
|
+
};
|
|
31
50
|
|
|
32
51
|
// src/lib.ts
|
|
33
52
|
var lib_exports = {};
|
|
@@ -151,25 +170,6 @@ var signalPath = () => {
|
|
|
151
170
|
mkdirSync(dir, { recursive: true });
|
|
152
171
|
return join(dir, "cockpit-dirty");
|
|
153
172
|
};
|
|
154
|
-
var DrillView = ({
|
|
155
|
-
title,
|
|
156
|
-
subtitle,
|
|
157
|
-
hints,
|
|
158
|
-
children
|
|
159
|
-
}) => {
|
|
160
|
-
const { rows } = useWindowSize();
|
|
161
|
-
return /* @__PURE__ */ jsx(Panel, { children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", height: rows - 2, paddingX: 1, children: [
|
|
162
|
-
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
163
|
-
/* @__PURE__ */ jsx(Text, { color: colors.accent, bold: true, children: title }),
|
|
164
|
-
subtitle ? /* @__PURE__ */ jsxs(Box, { marginTop: 1, children: [
|
|
165
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children: "Title: " }),
|
|
166
|
-
/* @__PURE__ */ jsx(Text, { children: subtitle })
|
|
167
|
-
] }) : null
|
|
168
|
-
] }),
|
|
169
|
-
/* @__PURE__ */ jsx(Box, { flexDirection: "column", flexGrow: 1, children }),
|
|
170
|
-
/* @__PURE__ */ jsx(FooterHints, { hints })
|
|
171
|
-
] }) });
|
|
172
|
-
};
|
|
173
173
|
var CANDIDATES = [
|
|
174
174
|
{ id: "claude", label: "Claude Code", cmd: "claude", acceptsPrompt: true },
|
|
175
175
|
{ id: "opencode", label: "opencode", cmd: "opencode" },
|