Commit d995b78
authored
[HDX-3919] Add @hyperdx/cli package — terminal TUI, source map upload, and agent-friendly commands (#2043)
## Summary
Adds `packages/cli` (`@hyperdx/cli`) — a unified CLI for HyperDX that provides an interactive TUI for searching/tailing logs and traces, source map upload (migrated from `hyperdx-js`), and agent-friendly commands for programmatic access.
Ref: HDX-3919
Ref: HDX-3920
### CLI Commands
```
hdx tui -s <url> # Interactive TUI (main command)
hdx sources -s <url> # List sources with ClickHouse schemas
hdx sources -s <url> --json # JSON output for agents / scripts
hdx dashboards -s <url> # List dashboards with tile summaries
hdx dashboards -s <url> --json # JSON output for agents / scripts
hdx query --source "Logs" --sql "SELECT count() FROM default.otel_logs"
hdx upload-sourcemaps -k <key> # Upload source maps (ported from hyperdx-js)
hdx auth login -s <url> # Sign in (interactive or -e/-p flags)
hdx auth status # Show auth status
hdx auth logout # Clear saved session
```
### Key Features
**Interactive TUI (`hdx tui`)**
- Table view with dynamic columns derived from query results (percentage-based widths)
- Follow mode (live tail) enabled by default, auto-pauses when detail panel is open
- Vim-like keybindings: j/k navigation, G/g jump, Ctrl+D/U half-page scroll
- `/` for Lucene search, `s` to edit SELECT clause in `$EDITOR`, `t` to edit time range
- Tab to cycle between sources and saved searches
- `w` to toggle line wrap
**Detail Panel (3 tabs, full-screen with Ctrl+D/U scrolling)**
- **Overview** — Structured view: Top Level Attributes, Log/Span Attributes, Resource Attributes
- **Column Values** — Full `SELECT *` row data with `__hdx_*` aliased columns
- **Trace** — Waterfall chart (port of `DBTraceWaterfallChart` DAG builder) with correlated log events, j/k span navigation, inverse highlight, Event Details section
**Agent-friendly commands**
- `hdx sources --json` — Full source metadata with ClickHouse `CREATE TABLE` DDL, expression mappings, and correlated source IDs. Detailed `--help` describes the JSON schema for LLM consumption. Schema queries run in parallel.
- `hdx dashboards --json` — Dashboard metadata with simplified tile summaries (name, type, source, sql). Resolves source names for human-readable output.
- `hdx query --source <name> --sql <query>` — Raw SQL execution against any source's ClickHouse connection. Supports `--format` for ClickHouse output formats (JSON, JSONEachRow, CSV, etc.).
**Source map upload (`hdx upload-sourcemaps`)**
- Ported from `hyperdx-js/packages/cli` to consolidate on a single `@hyperdx/cli` package
- Authenticates via service account API key (`-k` / `HYPERDX_SERVICE_KEY` env var)
- Globs `.js` and `.js.map` files, handles Next.js route groups
- Uploads to presigned URLs in parallel with retry (3 attempts) and progress
- Modernized: native `fetch` (Node 22+), ESM-compatible, proper TypeScript types
### Architecture
```
packages/cli/
├── src/
│ ├── cli.tsx # Commander CLI: tui, sources, dashboards, query,
│ │ # upload-sourcemaps, auth
│ ├── App.tsx # Ink app shell (login → source picker → EventViewer)
│ ├── sourcemaps.ts # Source map upload logic (ported from hyperdx-js)
│ ├── api/
│ │ ├── client.ts # ApiClient + ProxyClickhouseClient
│ │ └── eventQuery.ts # Query builders (renderChartConfig, raw SQL)
│ ├── components/
│ │ ├── EventViewer/ # Main TUI (9 files)
│ │ │ ├── EventViewer.tsx # Orchestrator (state, hooks, render shell)
│ │ │ ├── types.ts # Shared types & constants
│ │ │ ├── utils.ts # Row formatting functions
│ │ │ ├── SubComponents.tsx # Header, TabBar, SearchBar, Footer, HelpScreen, TableHeader
│ │ │ ├── TableView.tsx # Table rows rendering
│ │ │ ├── DetailPanel.tsx # Detail panel (overview/columns/trace tabs)
│ │ │ ├── useEventData.ts # Data fetching hook
│ │ │ └── useKeybindings.ts # Input handler hook
│ │ ├── TraceWaterfall/ # Trace chart (6 files)
│ │ │ ├── TraceWaterfall.tsx # Orchestrator + render
│ │ │ ├── types.ts # SpanRow, SpanNode, props
│ │ │ ├── utils.ts # Duration/status/bar helpers
│ │ │ ├── buildTree.ts # DAG builder (port of DBTraceWaterfallChart)
│ │ │ └── useTraceData.ts # Data fetching hook
│ │ ├── RowOverview.tsx
│ │ ├── ColumnValues.tsx
│ │ ├── LoginForm.tsx
│ │ └── SourcePicker.tsx
│ ├── shared/ # Ported from packages/app (@source annotated)
│ └── utils/ # Config, editor, log silencing
├── AGENTS.md
├── CONTRIBUTING.md
└── README.md
```
### Tech Stack
- **Ink v6.8.0** (React 19 for terminals) + Commander.js
- **@clickhouse/client** via ProxyClickhouseClient (routes through `/clickhouse-proxy`)
- **@hyperdx/common-utils** for query generation (`renderChartConfig`, `chSqlToAliasMap`)
- **glob v13** for source map file discovery
- **tsup** for bundling (all deps bundled via `noExternal: [/.*/]`, zero runtime deps)
- **Bun 1.3.11** for standalone binary compilation
- Session stored at `~/.config/hyperdx/cli/session.json`
### CI/CD (`release.yml`)
- CLI binaries compiled for macOS ARM64, macOS x64, and Linux x64
- GitHub Release created with download instructions
- Version-change gate: skips release if `cli-v{version}` tag already exists
- `softprops/action-gh-release` pinned to full SHA (v2.6.1) for supply chain safety
- Bun pinned to `1.3.11` for reproducible builds
- npm publishing handled by changesets
### Keybindings
| Key | Action |
|---|---|
| `j/k` | Navigate rows (or spans in Trace tab) |
| `l/Enter` | Expand row detail |
| `h/Esc` | Close detail / blur search |
| `G/g` | Jump to newest/oldest |
| `Ctrl+D/U` | Scroll half-page (table, detail panels, Event Details) |
| `/` | Search (global or detail filter) |
| `Tab` | Cycle sources/searches or detail tabs |
| `s` | Edit SELECT clause in $EDITOR |
| `t` | Edit time range in $EDITOR |
| `f` | Toggle follow mode (live tail) |
| `w` | Toggle line wrap |
| `?` | Help screen |
### Demo
#### Main Search View
<img width="1004" height="1014" alt="image" src="https://github.com/user-attachments/assets/bb6a7f00-38c9-4281-9915-c71b65d852f8" />
#### Event Details Overview
<img width="1003" height="1024" alt="image" src="https://github.com/user-attachments/assets/57025fa5-fddb-452a-9320-93465538d5b2" />
#### Trace Waterfall
<img width="1004" height="1029" alt="image" src="https://github.com/user-attachments/assets/3443c898-ea0d-47f3-acc5-edb7cdd31946" />1 parent 5de23e1 commit d995b78
File tree
41 files changed
+6765
-6
lines changed- .changeset
- .github/workflows
- packages/cli
- src
- api
- components
- EventViewer
- TraceWaterfall
- utils
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
41 files changed
+6765
-6
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
418 | 418 | | |
419 | 419 | | |
420 | 420 | | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
421 | 519 | | |
422 | 520 | | |
423 | 521 | | |
| |||
553 | 651 | | |
554 | 652 | | |
555 | 653 | | |
| 654 | + | |
556 | 655 | | |
557 | 656 | | |
558 | 657 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
0 commit comments