luciq-cli 0.1.0 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -0
- data/LICENSE +21 -0
- data/README.md +240 -14
- data/lib/luciq/api/client.rb +34 -14
- data/lib/luciq/cli.rb +47 -18
- data/lib/luciq/commands/auth.rb +1 -1
- data/lib/luciq/commands/query.rb +228 -0
- data/lib/luciq/commands/query_arguments.rb +179 -0
- data/lib/luciq/commands/upload.rb +83 -12
- data/lib/luciq/config.rb +2 -1
- data/lib/luciq/query_cli.rb +585 -0
- data/lib/luciq/upload_cli.rb +189 -0
- data/lib/luciq/version.rb +1 -1
- metadata +13 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8a0f4b1ed57b62e9807f17afddbd5e34b5fa411d504cd2fdabd5afc50521650c
|
|
4
|
+
data.tar.gz: b25294d1c535c880a7d8be44385bce9ccdc49bd8be7245ae8417d031177aad27
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cf5b2166bc9f2e6910feab38b73d90187d9a928d3207e703bcc97faa55fcd84b6398362150300207c850d49460d9c200e65957615be10c4309e0e61a7ec8e9af
|
|
7
|
+
data.tar.gz: f90266fa97e558b083630cda382d9febe7421a3e3f9c4e03935c93819e28ab26510ed6e2c1d154666b5aa634b44d74f667686155c5783c4b5e10510cf90a8999
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.0] - 2026-08-04
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **Breaking:** `luciq upload` commands now take `--slug` and `--mode` instead of `--app-token`, matching the query commands. Uploads authenticate with your CLI login, so no application token is needed.
|
|
15
|
+
- `luciq whoami` and `luciq upload` now call the Luciq API gateway instead of the public backend endpoints.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- `--tag-action` on `luciq bugs update` to control how `--tags` is applied: `append` (default), `replace`, or `remove`
|
|
20
|
+
- Homebrew installation: `brew install luciqai/tap/luciq-cli`
|
|
21
|
+
- MIT LICENSE
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- `luciq bugs update` now rejects `--clear-tags` combined with `--tag-action`, and no longer treats a tags-only change as an empty update
|
|
26
|
+
- Corrected the dashboard URL shown for creating a CLI token
|
|
27
|
+
|
|
28
|
+
## [0.2.0] - 2026-07-05
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- `luciq crashes` - Query crashes: `list`, `show`, `patterns`, `diagnostics`, `hangs`, `occurrence-tokens`, `occurrence`
|
|
33
|
+
- `luciq bugs` - Query and update bugs: `list`, `show`, `update` (status, priority, tags, duplicate marking)
|
|
34
|
+
- `luciq apm` - Query APM data: `groups`, `group`, `occurrence`, and funnels (`funnel-events`, `funnel-create`, `funnel-update`, `funnel-delete`)
|
|
35
|
+
- `luciq reviews list` - Query app reviews
|
|
36
|
+
- `luciq surveys` - Query surveys: `list`, `show`
|
|
37
|
+
- `luciq apps list` - List accessible applications
|
|
38
|
+
- `luciq insights` - Show aggregated app-health insights
|
|
39
|
+
- `luciq issues list` - List issues across sources ranked by impact
|
|
40
|
+
- `luciq opportunities` - Query opportunities: `list`, `show`
|
|
41
|
+
- `luciq alerts` - Manage alert rules: `list`, `show`, `init`, `create`, `update`, `delete`
|
|
42
|
+
- `luciq incidents` - Manage triggered alerts: `list`, `show`, `resolve`, `reopen`
|
|
43
|
+
- Typed filter flags with a raw `--filters` JSON escape hatch on query commands
|
|
44
|
+
|
|
10
45
|
## [0.1.0] - 2025-12-16
|
|
11
46
|
|
|
12
47
|
### Added
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Instabug, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Luciq CLI
|
|
2
2
|
|
|
3
|
-
Command-line interface for
|
|
3
|
+
Command-line interface for Luciq: upload symbol files and query or manage your
|
|
4
|
+
app data — crashes, bugs, APM, reviews, surveys, issues, opportunities, alerts,
|
|
5
|
+
and more.
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
@@ -13,14 +15,13 @@ gem install luciq-cli
|
|
|
13
15
|
### Using Homebrew (macOS/Linux)
|
|
14
16
|
|
|
15
17
|
```bash
|
|
16
|
-
brew
|
|
17
|
-
brew install luciq-cli
|
|
18
|
+
brew install luciqai/tap/luciq-cli
|
|
18
19
|
```
|
|
19
20
|
|
|
20
21
|
### From Source
|
|
21
22
|
|
|
22
23
|
```bash
|
|
23
|
-
git clone https://github.com/
|
|
24
|
+
git clone https://github.com/luciqai/luciq-cli.git
|
|
24
25
|
cd luciq-cli
|
|
25
26
|
bundle install
|
|
26
27
|
bundle exec rake install
|
|
@@ -30,7 +31,7 @@ bundle exec rake install
|
|
|
30
31
|
|
|
31
32
|
### 1. Authenticate
|
|
32
33
|
|
|
33
|
-
Generate a CLI token from your [Luciq Dashboard](https://dashboard.luciq.ai/company/cli), then:
|
|
34
|
+
Generate a CLI token from your [Luciq Dashboard](https://dashboard.luciq.ai/company/luciq-cli), then:
|
|
34
35
|
|
|
35
36
|
> **Self-hosted clusters:** Replace `dashboard.luciq.ai` with your cluster URL.
|
|
36
37
|
|
|
@@ -46,18 +47,20 @@ luciq login --auth-token YOUR_CLI_TOKEN
|
|
|
46
47
|
|
|
47
48
|
### 2. Upload Symbol Files
|
|
48
49
|
|
|
49
|
-
Upload Android mapping files (
|
|
50
|
+
Upload Android mapping files (`mapping.txt`):
|
|
50
51
|
|
|
51
52
|
```bash
|
|
52
|
-
luciq upload android-mapping mapping.
|
|
53
|
-
--app
|
|
53
|
+
luciq upload android-mapping mapping.txt \
|
|
54
|
+
--slug my-app \
|
|
55
|
+
--mode production \
|
|
54
56
|
--version-name 1.0.0 \
|
|
55
57
|
--version-code 1
|
|
56
58
|
```
|
|
57
59
|
|
|
58
60
|
| Option | Description |
|
|
59
61
|
|--------|-------------|
|
|
60
|
-
| `--
|
|
62
|
+
| `--slug` | Application slug (required) |
|
|
63
|
+
| `--mode` | Application mode, e.g., `production` (required) |
|
|
61
64
|
| `--version-name` | App version name, e.g., `1.0.0` (required) |
|
|
62
65
|
| `--version-code` | App version code, e.g., `1` (required) |
|
|
63
66
|
|
|
@@ -69,8 +72,220 @@ luciq upload android-mapping mapping.zip \
|
|
|
69
72
|
| `luciq logout` | Remove saved authentication |
|
|
70
73
|
| `luciq whoami` | Show current authenticated user |
|
|
71
74
|
| `luciq info` | Show CLI configuration |
|
|
72
|
-
| `luciq upload android-mapping FILE` | Upload Android mapping file |
|
|
73
75
|
| `luciq version` | Show CLI version |
|
|
76
|
+
| `luciq upload` | Upload symbol files (see below) |
|
|
77
|
+
| `luciq crashes` | Query crashes, hangs, and occurrences |
|
|
78
|
+
| `luciq bugs` | Query and update bugs |
|
|
79
|
+
| `luciq apm` | Query APM metrics and manage funnels |
|
|
80
|
+
| `luciq reviews` | Query app store reviews |
|
|
81
|
+
| `luciq surveys` | Query surveys and their responses |
|
|
82
|
+
| `luciq apps` | List accessible applications |
|
|
83
|
+
| `luciq issues` | List issues across sources, ranked by impact |
|
|
84
|
+
| `luciq opportunities` | Query product opportunities |
|
|
85
|
+
| `luciq alerts` | Manage alert rules |
|
|
86
|
+
| `luciq incidents` | Manage triggered alerts |
|
|
87
|
+
| `luciq insights` | Show aggregated app-health insights |
|
|
88
|
+
|
|
89
|
+
See [Query & management commands](#query--management-commands) for the full option
|
|
90
|
+
set of the data commands.
|
|
91
|
+
|
|
92
|
+
### Upload commands
|
|
93
|
+
|
|
94
|
+
Run `luciq upload help SUBCOMMAND` for the full options of any command.
|
|
95
|
+
|
|
96
|
+
**iOS**
|
|
97
|
+
|
|
98
|
+
| Command | File | Description |
|
|
99
|
+
|---------|------|-------------|
|
|
100
|
+
| `luciq upload ios-dsym FILE` | `.zip` | iOS dSYM symbols |
|
|
101
|
+
|
|
102
|
+
**Android**
|
|
103
|
+
|
|
104
|
+
| Command | File | Description |
|
|
105
|
+
|---------|------|-------------|
|
|
106
|
+
| `luciq upload android-mapping FILE` | `mapping.txt` | Proguard/R8 mapping file |
|
|
107
|
+
| `luciq upload android-ndk FILE` | `.zip` | NDK `.so` shared object files (`--arch`) |
|
|
108
|
+
|
|
109
|
+
**React Native**
|
|
110
|
+
|
|
111
|
+
| Command | File | Description |
|
|
112
|
+
|---------|------|-------------|
|
|
113
|
+
| `luciq upload react-native-ios-dsym FILE` | `.zip` | iOS native dSYM symbols |
|
|
114
|
+
| `luciq upload react-native-ios-sourcemap FILE` | `.json`/`.txt` | iOS JavaScript source map |
|
|
115
|
+
| `luciq upload react-native-android-mapping FILE` | `mapping.txt` | Android native Proguard/R8 mapping |
|
|
116
|
+
| `luciq upload react-native-android-sourcemap FILE` | `.json`/`.txt` | Android JavaScript source map |
|
|
117
|
+
| `luciq upload react-native-ndk FILE` | `.zip` | NDK `.so` shared object files (`--arch`) |
|
|
118
|
+
|
|
119
|
+
**Flutter**
|
|
120
|
+
|
|
121
|
+
| Command | File | Description |
|
|
122
|
+
|---------|------|-------------|
|
|
123
|
+
| `luciq upload flutter-ios-dsym FILE` | `.zip` | iOS native dSYM symbols |
|
|
124
|
+
| `luciq upload flutter-ios-sourcemap FILE` | `.zip` | iOS Dart symbol files |
|
|
125
|
+
| `luciq upload flutter-android-mapping FILE` | `mapping.txt` | Android native Proguard/R8 mapping |
|
|
126
|
+
| `luciq upload flutter-android-sourcemap FILE` | `.zip` | Android Dart symbol files |
|
|
127
|
+
| `luciq upload flutter-ndk FILE` | `.zip` | NDK `.so` shared object files (`--arch`) |
|
|
128
|
+
|
|
129
|
+
Common options: `--slug` and `--mode` are required for every command — uploads use
|
|
130
|
+
your CLI login, the same as query commands. dSYM commands (`*-ios-dsym`) need only
|
|
131
|
+
`--slug` / `--mode`. Mapping, source-map, and
|
|
132
|
+
Flutter Dart-symbol commands also require `--version-name` / `--version-code`
|
|
133
|
+
(React Native source-map commands additionally accept `--codepush`). NDK commands
|
|
134
|
+
require `--version-name` and `--arch` (`armeabi-v7a`, `arm64-v8a`, `x86`, `x86_64`)
|
|
135
|
+
— not `--version-code`.
|
|
136
|
+
|
|
137
|
+
## Query & management commands
|
|
138
|
+
|
|
139
|
+
Beyond uploading symbols, the CLI queries and manages your Luciq data. Every
|
|
140
|
+
response is printed as pretty-printed JSON, so it pipes cleanly into tools like
|
|
141
|
+
`jq`.
|
|
142
|
+
|
|
143
|
+
### Shared options
|
|
144
|
+
|
|
145
|
+
Most data commands target one application in one environment and share a common
|
|
146
|
+
set of options:
|
|
147
|
+
|
|
148
|
+
| Option | Description |
|
|
149
|
+
|--------|-------------|
|
|
150
|
+
| `--slug` | Application slug (required) |
|
|
151
|
+
| `--mode` | Environment: `production`, `beta`, `staging`, `alpha`, `qa`, `development` (required) |
|
|
152
|
+
| `--offset`, `--limit` | Pagination |
|
|
153
|
+
| `--sort-by`, `--direction` | Sort field and direction (`asc`/`desc`) — some commands use `--sort-direction` instead |
|
|
154
|
+
| `--filters` | Raw filter JSON object, merged with the typed filter flags (typed flags win on key conflicts) |
|
|
155
|
+
|
|
156
|
+
Common filters have dedicated typed flags (`--status`, `--platform`,
|
|
157
|
+
`--app-version`, …). Anything a tool supports but that has no flag can be passed
|
|
158
|
+
through `--filters`, e.g. `--filters '{"devices":["iPhone15,2"],"os_versions":["17.4"]}'`.
|
|
159
|
+
Run `luciq <group> help <subcommand>` for the full option list and the filter
|
|
160
|
+
keys each command accepts.
|
|
161
|
+
|
|
162
|
+
### Crashes
|
|
163
|
+
|
|
164
|
+
`luciq crashes SUBCOMMAND`
|
|
165
|
+
|
|
166
|
+
| Subcommand | Description |
|
|
167
|
+
|------------|-------------|
|
|
168
|
+
| `list` | List crashes. Flags: `--status` (open/closed/in_progress), `--platform` (IOS/ANDROID/DART/JAVASCRIPT), `--type` (CRASH/ANR/OOM/NON_FATAL), `--app-version` |
|
|
169
|
+
| `show --number N` | Details for one crash |
|
|
170
|
+
| `patterns --number N` | Grouped patterns. Flags: `--pattern-key`, `--sort-by`, `--direction` |
|
|
171
|
+
| `diagnostics --number N` | Diagnostics for one crash |
|
|
172
|
+
| `hangs` | List app hangs (same filters as `list`) |
|
|
173
|
+
| `occurrence-tokens --number N` | Occurrence cursor tokens. Flags: `--current-token`, `--direction` (first/last) |
|
|
174
|
+
| `occurrence --number N --ulid U` | Details for a single occurrence |
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
luciq crashes list --slug my-app --mode production --status open --limit 20
|
|
178
|
+
luciq crashes show --slug my-app --mode production --number 42
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Bugs
|
|
182
|
+
|
|
183
|
+
`luciq bugs SUBCOMMAND`
|
|
184
|
+
|
|
185
|
+
| Subcommand | Description |
|
|
186
|
+
|------------|-------------|
|
|
187
|
+
| `list` | List bugs. Flags: `--status` (new/closed/in_progress), `--priority` (na/trivial/minor/major/blocker), `--app-version` |
|
|
188
|
+
| `show --number N` | Details for one bug |
|
|
189
|
+
| `update --number N` | Update a bug. Flags: `--status`, `--priority`, `--tags`, `--tag-action`, `--clear-tags`, `--duplicate-of`, `--action` |
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
luciq bugs update --slug my-app --mode production --number 7 --status closed --priority major
|
|
193
|
+
luciq bugs update --slug my-app --mode production --number 7 --duplicate-of 3
|
|
194
|
+
luciq bugs update --slug my-app --mode production --number 7 --tags urgent regression
|
|
195
|
+
luciq bugs update --slug my-app --mode production --number 7 --tags stale --tag-action remove
|
|
196
|
+
luciq bugs update --slug my-app --mode production --number 7 --tags only-this --tag-action replace
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Provide at least one change. Duplicate marking (`--duplicate-of` / `--action`)
|
|
200
|
+
can't be combined with `--status`/`--priority`. Tags: `--tags` appends to the existing
|
|
201
|
+
tags by default; `--tag-action replace` sets `--tags` as the full list (removing others),
|
|
202
|
+
`--tag-action remove` deletes `--tags` and keeps the rest; `--clear-tags` removes all.
|
|
203
|
+
|
|
204
|
+
### APM
|
|
205
|
+
|
|
206
|
+
`luciq apm SUBCOMMAND`
|
|
207
|
+
|
|
208
|
+
| Subcommand | Description |
|
|
209
|
+
|------------|-------------|
|
|
210
|
+
| `groups --metric M` | Rank groups worst-first. `--metric`: network, launch, flows, screen_loading, frame_drop, funnels. `--sort` is a JSON object `{"by":…,"direction":…}` |
|
|
211
|
+
| `group --metric M` | Panels for one group; identify with `--group-uuid` or `--group-url`. `--views` is a JSON array (default `["summary"]`); `--method` applies to network |
|
|
212
|
+
| `occurrence --metric M --selector S` | Inspect occurrences (`--selector`: worst/by_token/list). Flags: `--token`, `--current-token`, `--direction`, `--limit` |
|
|
213
|
+
| `funnel-events` | List events pickable for funnels. Flags: `--event-type`, `--q`, `--limit` |
|
|
214
|
+
| `funnel-create --name N --events JSON` | Create a funnel from 2–20 steps |
|
|
215
|
+
| `funnel-update --ulid U` | Update a funnel (`--name`, `--events`) |
|
|
216
|
+
| `funnel-delete --ulid U` | Delete a funnel |
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
luciq apm groups --slug my-app --mode production --metric network \
|
|
220
|
+
--sort '{"by":"p95","direction":"desc"}'
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Reviews
|
|
224
|
+
|
|
225
|
+
`luciq reviews list` — Flags: `--rating` (1–5), `--country`, `--os` (ios/android),
|
|
226
|
+
`--sort-by date`, `--sort-direction`.
|
|
227
|
+
|
|
228
|
+
### Surveys
|
|
229
|
+
|
|
230
|
+
`luciq surveys SUBCOMMAND`
|
|
231
|
+
|
|
232
|
+
| Subcommand | Description |
|
|
233
|
+
|------------|-------------|
|
|
234
|
+
| `list` | List surveys. Flags: `--type` (0=custom 1=nps 2=app_store), `--status` (0=draft 1=published 2=paused) |
|
|
235
|
+
| `show --id N` | A survey's questions and response statistics. `--page` paginates responses |
|
|
236
|
+
|
|
237
|
+
### Apps
|
|
238
|
+
|
|
239
|
+
`luciq apps list` — List the applications you can access (no `--slug`/`--mode`).
|
|
240
|
+
Optional `--platform` (ios/android/react_native/flutter).
|
|
241
|
+
|
|
242
|
+
### Insights
|
|
243
|
+
|
|
244
|
+
`luciq insights --slug my-app --mode production` — Aggregated app-health insights.
|
|
245
|
+
Narrow with `--filters` (`date_ms`, `app_version`).
|
|
246
|
+
|
|
247
|
+
### Issues
|
|
248
|
+
|
|
249
|
+
`luciq issues list` — Issues across crashes, APM, AI, and bugs, ranked by Apdex
|
|
250
|
+
impact. Flags: `--limit`, `--sort-by` (apdex_impact/occurrences_counter),
|
|
251
|
+
`--sort-direction`, `--top-issues` (curated shortlist), `--pagination`
|
|
252
|
+
(per-source cursor tokens JSON).
|
|
253
|
+
|
|
254
|
+
### Opportunities
|
|
255
|
+
|
|
256
|
+
`luciq opportunities SUBCOMMAND`
|
|
257
|
+
|
|
258
|
+
| Subcommand | Description |
|
|
259
|
+
|------------|-------------|
|
|
260
|
+
| `list` | List opportunities. Flags: `--status`, `--priority` (1–4/unset), `--team-id` |
|
|
261
|
+
| `show --id N` | Details for one opportunity |
|
|
262
|
+
|
|
263
|
+
### Alerts
|
|
264
|
+
|
|
265
|
+
`luciq alerts SUBCOMMAND` — Manage alert rules.
|
|
266
|
+
|
|
267
|
+
| Subcommand | Description |
|
|
268
|
+
|------------|-------------|
|
|
269
|
+
| `list` | List rules (`--sort-by`, `--sort-direction`) |
|
|
270
|
+
| `show --ulid U` | Show one rule |
|
|
271
|
+
| `init` | Show the menu (types, triggers, conditions, actions) for building a rule |
|
|
272
|
+
| `create --payload JSON` | Create a rule |
|
|
273
|
+
| `update --ulid U --payload JSON` | Update a rule |
|
|
274
|
+
| `delete --ulid U` | Delete a rule |
|
|
275
|
+
|
|
276
|
+
Run `luciq alerts init` first to discover the valid rule building blocks, then
|
|
277
|
+
pass the rule body as `--payload`.
|
|
278
|
+
|
|
279
|
+
### Incidents
|
|
280
|
+
|
|
281
|
+
`luciq incidents SUBCOMMAND` — Manage triggered alerts.
|
|
282
|
+
|
|
283
|
+
| Subcommand | Description |
|
|
284
|
+
|------------|-------------|
|
|
285
|
+
| `list` | List incidents. Flags: `--sort-by`, `--sort-direction`, `--status`, `--type` |
|
|
286
|
+
| `show --ulid U` | Show one incident |
|
|
287
|
+
| `resolve --ulid U` | Resolve an incident |
|
|
288
|
+
| `reopen --ulid U` | Reopen an incident |
|
|
74
289
|
|
|
75
290
|
## Configuration
|
|
76
291
|
|
|
@@ -112,14 +327,25 @@ url=https://api.your-cluster.luciq.ai
|
|
|
112
327
|
|
|
113
328
|
## Development
|
|
114
329
|
|
|
115
|
-
|
|
116
|
-
git clone https://github.com/Instabug/luciq-cli.git
|
|
117
|
-
cd luciq-cli
|
|
118
|
-
bundle install
|
|
330
|
+
Clone the repo and install dependencies as in [From Source](#from-source), then:
|
|
119
331
|
|
|
332
|
+
```bash
|
|
120
333
|
# Run tests
|
|
121
334
|
bundle exec rspec
|
|
122
335
|
|
|
123
336
|
# Test locally
|
|
124
337
|
bundle exec bin/luciq --help
|
|
125
338
|
```
|
|
339
|
+
|
|
340
|
+
## Releasing
|
|
341
|
+
|
|
342
|
+
After publishing a new gem version to RubyGems, sync the Homebrew formula in
|
|
343
|
+
the [homebrew-tap](https://github.com/luciqai/homebrew-tap) repo:
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
bundle exec rake formula:bump # writes to ../homebrew-tap, override with TAP_DIR
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Open a pull request in the tap repo with the result: Homebrew users stay on
|
|
350
|
+
the previous version until the bumped formula lands on its `main` branch.
|
|
351
|
+
`brew livecheck luciq-cli` reports when the formula lags RubyGems.
|
data/lib/luciq/api/client.rb
CHANGED
|
@@ -15,31 +15,49 @@ module Luciq
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def whoami
|
|
18
|
-
uri = build_uri('/api/
|
|
18
|
+
uri = build_uri('/api/cli/whoami')
|
|
19
19
|
request = Net::HTTP::Get.new(uri)
|
|
20
20
|
apply_headers(request)
|
|
21
21
|
execute(uri, request)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
# Invokes a query tool by name with a hash of arguments (slug, mode,
|
|
25
|
+
# filters, pagination, ...) sent as a JSON body.
|
|
26
|
+
def invoke_tool(tool_name, arguments = {})
|
|
27
|
+
uri = build_uri("/api/cli/tools/#{tool_name}")
|
|
28
|
+
request = Net::HTTP::Post.new(uri)
|
|
29
|
+
request['Content-Type'] = 'application/json'
|
|
30
|
+
request.body = arguments.to_json
|
|
31
|
+
apply_headers(request)
|
|
32
|
+
execute(uri, request)
|
|
33
|
+
end
|
|
26
34
|
|
|
35
|
+
def upload(command, file_path, fields = {})
|
|
36
|
+
uri = build_uri("/api/cli/uploads/#{command}")
|
|
27
37
|
File.open(file_path, 'rb') do |file|
|
|
28
38
|
params = {
|
|
29
|
-
'
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
'app_version_name' => version_name
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
request = Net::HTTP::Post::Multipart.new(uri.path, params)
|
|
36
|
-
apply_headers(request)
|
|
37
|
-
execute(uri, request)
|
|
39
|
+
'file' => UploadIO.new(file, content_type_for(file_path), File.basename(file_path))
|
|
40
|
+
}.merge(fields)
|
|
41
|
+
post_multipart(uri, params)
|
|
38
42
|
end
|
|
39
43
|
end
|
|
40
44
|
|
|
41
45
|
private
|
|
42
46
|
|
|
47
|
+
def post_multipart(uri, params)
|
|
48
|
+
request = Net::HTTP::Post::Multipart.new(uri.path, params)
|
|
49
|
+
apply_headers(request)
|
|
50
|
+
execute(uri, request)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def content_type_for(file_path)
|
|
54
|
+
case File.extname(file_path).downcase
|
|
55
|
+
when '.json' then 'application/json'
|
|
56
|
+
when '.txt' then 'text/plain'
|
|
57
|
+
else 'application/octet-stream'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
43
61
|
def build_uri(path)
|
|
44
62
|
URI("#{@base_url}#{path}")
|
|
45
63
|
end
|
|
@@ -56,9 +74,11 @@ module Luciq
|
|
|
56
74
|
http.read_timeout = 300
|
|
57
75
|
|
|
58
76
|
response = http.request(request)
|
|
59
|
-
|
|
77
|
+
raise "Request failed (#{response.code}): #{response.body}" unless response.is_a?(Net::HTTPSuccess)
|
|
60
78
|
|
|
61
|
-
|
|
79
|
+
JSON.parse(response.body)
|
|
80
|
+
rescue JSON::ParserError
|
|
81
|
+
response.body
|
|
62
82
|
end
|
|
63
83
|
end
|
|
64
84
|
end
|
data/lib/luciq/cli.rb
CHANGED
|
@@ -3,25 +3,10 @@
|
|
|
3
3
|
require 'thor'
|
|
4
4
|
require 'luciq/version'
|
|
5
5
|
require 'luciq/commands/auth'
|
|
6
|
-
require 'luciq/
|
|
6
|
+
require 'luciq/upload_cli'
|
|
7
|
+
require 'luciq/query_cli'
|
|
7
8
|
|
|
8
9
|
module Luciq
|
|
9
|
-
class UploadCLI < Thor
|
|
10
|
-
desc 'android-mapping FILE', 'Upload Android mapping file'
|
|
11
|
-
long_desc <<~DESC
|
|
12
|
-
Upload Android mapping files to Luciq for crash symbolication.
|
|
13
|
-
File format: .zip containing a single text file
|
|
14
|
-
Example:
|
|
15
|
-
luciq upload android-mapping mapping.zip --app-token APP_TOKEN --version-name 1.0.0 --version-code 1
|
|
16
|
-
DESC
|
|
17
|
-
option :app_token, type: :string, required: true, desc: 'Your Luciq application token'
|
|
18
|
-
option :version_name, type: :string, required: true, desc: 'App version name (e.g., 1.0.0)'
|
|
19
|
-
option :version_code, type: :string, required: true, desc: 'App version code (e.g., 1)'
|
|
20
|
-
def android_mapping(file)
|
|
21
|
-
Commands::Upload.new(options).android_mapping(file)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
10
|
class CLI < Thor
|
|
26
11
|
def self.exit_on_failure?
|
|
27
12
|
true
|
|
@@ -30,7 +15,7 @@ module Luciq
|
|
|
30
15
|
desc 'login', 'Authenticate with Luciq'
|
|
31
16
|
long_desc <<~DESC
|
|
32
17
|
Authenticate with Luciq using a CLI token.
|
|
33
|
-
Generate a CLI token from your Luciq dashboard: https://dashboard.luciq.ai/company/cli
|
|
18
|
+
Generate a CLI token from your Luciq dashboard: https://dashboard.luciq.ai/company/luciq-cli
|
|
34
19
|
The token will be saved in ~/.luciqrc
|
|
35
20
|
DESC
|
|
36
21
|
option :auth_token, type: :string, desc: 'CLI authentication token'
|
|
@@ -56,6 +41,50 @@ module Luciq
|
|
|
56
41
|
desc 'upload SUBCOMMAND', 'Upload symbol files to Luciq'
|
|
57
42
|
subcommand 'upload', UploadCLI
|
|
58
43
|
|
|
44
|
+
desc 'crashes SUBCOMMAND', 'Query crashes (list, show, patterns, diagnostics, hangs, occurrence-tokens, occurrence)'
|
|
45
|
+
subcommand 'crashes', CrashesCLI
|
|
46
|
+
|
|
47
|
+
desc 'bugs SUBCOMMAND', 'Query bugs (list, show, update)'
|
|
48
|
+
subcommand 'bugs', BugsCLI
|
|
49
|
+
|
|
50
|
+
desc 'apm SUBCOMMAND', 'Query APM data (groups, group, occurrence, funnels)'
|
|
51
|
+
subcommand 'apm', ApmCLI
|
|
52
|
+
|
|
53
|
+
desc 'reviews SUBCOMMAND', 'Query app reviews (list)'
|
|
54
|
+
subcommand 'reviews', ReviewsCLI
|
|
55
|
+
|
|
56
|
+
desc 'surveys SUBCOMMAND', 'Query surveys (list, show)'
|
|
57
|
+
subcommand 'surveys', SurveysCLI
|
|
58
|
+
|
|
59
|
+
desc 'apps SUBCOMMAND', 'List accessible applications'
|
|
60
|
+
subcommand 'apps', AppsCLI
|
|
61
|
+
|
|
62
|
+
desc 'issues SUBCOMMAND', 'Query issues ranked by impact (list)'
|
|
63
|
+
subcommand 'issues', IssuesCLI
|
|
64
|
+
|
|
65
|
+
desc 'opportunities SUBCOMMAND', 'Query opportunities (list, show)'
|
|
66
|
+
subcommand 'opportunities', OpportunitiesCLI
|
|
67
|
+
|
|
68
|
+
desc 'alerts SUBCOMMAND', 'Manage alert rules (list, show, init, create, update, delete)'
|
|
69
|
+
subcommand 'alerts', AlertsCLI
|
|
70
|
+
|
|
71
|
+
desc 'incidents SUBCOMMAND', 'Manage triggered alerts (list, show, resolve, reopen)'
|
|
72
|
+
subcommand 'incidents', IncidentsCLI
|
|
73
|
+
|
|
74
|
+
desc 'insights', 'Show aggregated app-health insights for an application'
|
|
75
|
+
long_desc(<<~DESC, wrap: false)
|
|
76
|
+
Show aggregated app-health insights for an application.
|
|
77
|
+
|
|
78
|
+
Filters via --filters:
|
|
79
|
+
date_ms {"gte": <ms>, "lte": <ms>}
|
|
80
|
+
app_version ["1.2.3", ...]
|
|
81
|
+
DESC
|
|
82
|
+
QueryOptions.app(self)
|
|
83
|
+
QueryOptions.raw_filters(self)
|
|
84
|
+
def insights
|
|
85
|
+
Commands::Query.new(options).insights
|
|
86
|
+
end
|
|
87
|
+
|
|
59
88
|
desc 'version', 'Show CLI version'
|
|
60
89
|
def version
|
|
61
90
|
puts "luciq-cli #{Luciq::VERSION}"
|
data/lib/luciq/commands/auth.rb
CHANGED
|
@@ -16,7 +16,7 @@ module Luciq
|
|
|
16
16
|
unless token
|
|
17
17
|
puts 'Login to Luciq'
|
|
18
18
|
puts '=' * 40
|
|
19
|
-
puts 'Generate a CLI token from your Luciq dashboard: https://dashboard.luciq.ai/company/cli'
|
|
19
|
+
puts 'Generate a CLI token from your Luciq dashboard: https://dashboard.luciq.ai/company/luciq-cli'
|
|
20
20
|
puts
|
|
21
21
|
puts "Note: For self-hosted clusters, replace 'dashboard' with your cluster name."
|
|
22
22
|
puts
|