jira-dashboard 0.1.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/README.md ADDED
@@ -0,0 +1,219 @@
1
+ # jira-dashboard (`jdb`)
2
+
3
+ A full-screen terminal dashboard for Jira Cloud, built with [Ink](https://github.com/vadimdemedes/ink).
4
+
5
+ ```
6
+ ┌─ last 14 days · 41.5h total ──────┬─ my open tickets (3/12) ─────────────────┐
7
+ │ Tue 28 Jul 7.5h MR-4 │ ▸ MR-3 In Review Fix the flaky test │
8
+ │ Wed 29 Jul 6.0h MR-1, MR-2 │ MR-4 In Progress Add worklog panel │
9
+ ├───────────────────────────────────┴──────────────────────────────────────────┤
10
+ │ MR-3 · 5.5h over 14d · 4h = 1 bar │ MR-3 · .../browse/MR-3 │
11
+ │ │ Platform › MR-100 Q3 push › MR-3 │
12
+ │ ██ ██ │ Fix the flaky test │
13
+ │ ▄▄ ██ ▄▄ ██ ██ │ type Bug │
14
+ │ 16 17 18 19 20 21 22 … │ status In Review │
15
+ └───────────────────────────────────┴──────────────────────────────────────────┘
16
+ ```
17
+
18
+ - **Top left** — hours you logged on each of the last 14 days (oldest first, so today is at the
19
+ bottom), plus the issues you logged against.
20
+ - **Top right** — your open tickets (not done, not cancelled/closed, not in the backlog), selectable
21
+ by keyboard or mouse.
22
+ - **Bottom left** — bar chart of the hours *you* logged on the **selected** ticket, day by day over
23
+ the same 14 days. The scale is fixed so bars are comparable between tickets and between runs: 2h is
24
+ half a row, 4h one row, 8h two rows; anything logged below 2h gets a thin mark so it stays visible.
25
+ - **Bottom right** — preview of the selected ticket: parent breadcrumbs, status, assignee, reporter,
26
+ priority, labels, the hours *you* logged and on which dates, total logged by everyone, and the
27
+ description.
28
+
29
+ ## Install
30
+
31
+ ```sh
32
+ npm install -g jira-dashboard
33
+ jdb
34
+ ```
35
+
36
+ ## Configure
37
+
38
+ Everything comes from the Jira Cloud REST API, authenticated with an
39
+ [API token](https://id.atlassian.com/manage-profile/security/api-tokens).
40
+
41
+ ```sh
42
+ export JIRA_BASE_URL="https://your-team.atlassian.net"
43
+ export JIRA_EMAIL="you@example.com"
44
+ export JIRA_API_TOKEN="…"
45
+ ```
46
+
47
+ Or write `~/.config/jira-dashboard/config.json` (environment variables win):
48
+
49
+ ```json
50
+ {
51
+ "baseUrl": "https://your-team.atlassian.net",
52
+ "email": "you@example.com",
53
+ "apiToken": "…",
54
+ "issuesJql": "assignee = currentUser() AND statusCategory != Done AND status NOT IN (\"Cancelled\", \"Closed\", \"Backlog\") ORDER BY updated DESC",
55
+ "worklogDays": 14
56
+ }
57
+ ```
58
+
59
+ `issuesJql` is worth customising: status names vary per site, and some boards model the backlog
60
+ by sprint rather than by status — in that case append `AND sprint IS NOT EMPTY`.
61
+
62
+ ## Keys
63
+
64
+ | Key | Action |
65
+ | --- | --- |
66
+ | `↑` `↓` / `j` `k` | Move within the focused panel |
67
+ | `Enter` | Open the selected ticket in your default browser (tickets panel only) |
68
+ | `PgUp` `PgDn` | Page through the focused panel |
69
+ | `Home` / `End` | Jump to the first / last item in the focused panel |
70
+ | `g` / `G` | Jump to first / last ticket |
71
+ | `Tab` / `Shift+Tab` | Cycle panels (worklogs → tickets → preview) |
72
+ | Click | Select a ticket / focus a panel |
73
+ | Wheel | Scroll the panel under the cursor |
74
+ | `r` | Reload both panels |
75
+ | `q` / `Esc` / `Ctrl+C` | Quit |
76
+
77
+ ## Development
78
+
79
+ ```sh
80
+ npm install
81
+ npm run dev # run from TypeScript source, no build step
82
+ npm run build # bundle to dist/cli.js with esbuild
83
+ npm run typecheck # tsc --noEmit
84
+ npm run check # lint + typecheck + build; run before publishing
85
+ npm run lint
86
+ npm run lint:fix
87
+ npm run lint:staged # lint-staged, for a pre-commit hook
88
+ ```
89
+
90
+ To run `lint:staged` automatically, add a `pre-commit` hook that calls `npm run lint:staged`.
91
+
92
+ ### Build
93
+
94
+ `npm run build` bundles `src/cli.tsx` into a single ESM file at `dist/cli.js` and marks it
95
+ executable. The shebang from the entry file is preserved, which is what lets `jdb` run directly.
96
+
97
+ ```sh
98
+ npm run build
99
+ node dist/cli.js --version
100
+ ```
101
+
102
+ Two properties of the bundle worth knowing:
103
+
104
+ - **Relative imports are written without a `.js` extension.** Node's ESM loader would reject that,
105
+ but esbuild resolves the specifiers at build time and `tsx` does the same in dev. `tsc` is
106
+ typecheck-only (`noEmit`), so it can never emit an unresolvable import.
107
+ - **Runtime dependencies stay external** (`--packages=external`), so only this project's own source
108
+ is bundled; `ink` and `react` are installed normally from `dependencies`.
109
+
110
+ `prepublishOnly` runs `npm run check`, so a publish rebuilds `dist/` and aborts on a lint or type
111
+ error rather than shipping one.
112
+
113
+ ### Run it locally as a global command
114
+
115
+ For day-to-day use, symlink the global `jdb` at your working copy:
116
+
117
+ ```sh
118
+ npm link # jdb -> <this repo>/dist/cli.js
119
+ npm run build # after each source change; jdb picks it up immediately
120
+ ```
121
+
122
+ To test what users actually get instead — a frozen copy built from the real tarball:
123
+
124
+ ```sh
125
+ npm pack
126
+ npm install -g ./jira-dashboard-0.1.0.tgz
127
+ jdb --version
128
+ ```
129
+
130
+ Undo either with `npm uninstall -g jira-dashboard` (or `npm unlink -g jira-dashboard`).
131
+
132
+ ### Debugging
133
+
134
+ **Never use `console.log`.** Stdout is the UI: writing to it corrupts the frame Ink is drawing.
135
+ Log to stderr and redirect it to a file, then watch that file from another terminal:
136
+
137
+ ```sh
138
+ # in the code: process.stderr.write(`selected=${key}\n`);
139
+ jdb 2> /tmp/jdb.log
140
+ tail -f /tmp/jdb.log # in a second terminal
141
+ ```
142
+
143
+ **Readable stack traces.** `dist/cli.js` is a bundle, so traces point at bundle offsets by default.
144
+ The build emits a source map; turn it on to get original file and line numbers:
145
+
146
+ ```sh
147
+ node --enable-source-maps dist/cli.js
148
+ ```
149
+
150
+ **Breakpoints.** Attach a debugger and open `chrome://inspect`, or use your editor's Node attach
151
+ config. Run from source so you are stepping through TypeScript rather than the bundle:
152
+
153
+ ```sh
154
+ node --inspect-brk --import tsx src/cli.tsx
155
+ ```
156
+
157
+ **Develop without hitting real Jira.** The app talks to nothing but the REST API, so pointing it at a
158
+ local stub is enough to work offline and to exercise edge cases (no worklogs, a ticket with no
159
+ sprint, a 401). Serve JSON for `/rest/api/3/myself`, `/rest/api/3/field`, `/rest/api/3/search/jql`,
160
+ and `/rest/api/3/issue/:key/worklog`, then:
161
+
162
+ ```sh
163
+ JIRA_BASE_URL=http://localhost:7311 JIRA_EMAIL=a@b.c JIRA_API_TOKEN=t npm run dev
164
+ ```
165
+
166
+ **Inspect the rendering non-interactively.** Handy in a script or when a layout bug only appears at a
167
+ particular size — `tmux` gives you the finished frame as text:
168
+
169
+ ```sh
170
+ tmux new-session -d -s jdb -x 130 -y 40 'jdb'
171
+ sleep 4
172
+ tmux capture-pane -p -t jdb # prints the rendered screen
173
+ tmux kill-session -t jdb
174
+ ```
175
+
176
+ Common failure modes: if the terminal is left in a broken state after a crash, run `reset`. If panel
177
+ content wraps or the panel title disappears, a fixed-width panel is being flex-shrunk or its content
178
+ is one row taller than its height — see `PanelFrame` and the row-count arithmetic in each panel.
179
+
180
+ ## Publishing to npm
181
+
182
+ The package publishes as **`jira-dashboard`** and installs the **`jdb`** command. Only `dist/` and
183
+ `README.md` ship (`files` in `package.json`); source and configs stay out of the tarball.
184
+
185
+ ```sh
186
+ # 1. Authenticate (once per machine)
187
+ npm login
188
+ npm whoami
189
+
190
+ # 2. Make sure it is releasable (lint + typecheck + build)
191
+ npm run check
192
+
193
+ # 3. Inspect exactly what will be uploaded — no files are published by this
194
+ npm pack --dry-run
195
+
196
+ # 4. Bump the version (also creates a git tag when this is a git repo;
197
+ # add --no-git-tag-version if it is not, or if you tag separately)
198
+ npm version patch # or: minor | major
199
+
200
+ # 5. Publish. prepublishOnly rebuilds dist/ first.
201
+ npm publish
202
+
203
+ # 6. Verify the published artifact
204
+ npm view jira-dashboard version
205
+ npx --yes jira-dashboard@latest --version
206
+ ```
207
+
208
+ Notes:
209
+
210
+ - **The name `jira-dashboard` was unclaimed on the public registry as of this writing**, but that can
211
+ change at any time. If `npm publish` fails with `E403`, the name is taken — publish under a scope
212
+ instead (`@yourname/jira-dashboard`), which additionally requires `npm publish --access public`
213
+ since scoped packages default to private.
214
+ - **Publishing is effectively permanent.** Unpublishing is only allowed within 72 hours and a version
215
+ number can never be reused. Prefer `npm deprecate jira-dashboard@1.2.3 "reason"` for a bad release
216
+ and ship a fix as a new version.
217
+ - **`engines` requires Node ≥ 20** (the code uses `AbortSignal.timeout` and built-in `fetch`).
218
+ - To rehearse the whole flow without touching the public registry, publish to a local registry such
219
+ as [Verdaccio](https://verdaccio.org/): `npm publish --registry http://localhost:4873`.