@fatecannotbealtered-/jira-cli 1.0.5 → 1.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/CHANGELOG.md CHANGED
@@ -7,6 +7,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.1.0] - 2026-06-06
11
+
12
+ ### Added
13
+
14
+ - **Agent JSON envelope** — default JSON success and failure responses now share a stable envelope: `ok`, `schema_version`, `data`/`error`, and `meta.duration_ms`.
15
+ - **Confirm-token write flow** — JSON write commands now support the non-interactive `--dry-run` → `--confirm <token>` flow. Dry-run responses include a change preview, `confirm_token`, and `expires_at`; execution validates that the token still matches the operation.
16
+ - **Self-description commands** — added `context`, and expanded `reference` and `doctor` output for agent discovery and environment checks.
17
+ - **Structured error taxonomy** — error envelopes now include stable `E_*` codes and `retryable` hints for automated retry decisions.
18
+
19
+ ### Changed
20
+
21
+ - **JSON is the agent contract** — stdout now contains exactly one JSON document for normal command responses; human-readable output requires `--format text`.
22
+ - **Error JSON moved to stdout** — machine-readable failures now use the same stdout channel and envelope shape as successes. Progress, prompts, warnings, and text-mode errors remain on stderr.
23
+ - **Exit code semantics** — exit codes now follow the agent contract: `2` bad args, `3` not found, `4` auth/permission, `5` confirmation required, `6` conflict, `7` retryable transient failure, `8` timeout.
24
+ - **Interactive login is text-only** — default JSON mode requires `jira-cli login --host <url> --token <pat>`; interactive login requires `--format text`.
25
+ - **`doctor` output** — JSON output now reports a `checks` list with `check`, `status`, `message`, and `fix` fields instead of the old `authValid` shape.
26
+
27
+ ### Fixed
28
+
29
+ - **JSON write safety** — confirmed JSON writes no longer fall through to stdin prompts after token validation.
30
+ - **Stable confirmation hashing** — write-command confirm tokens include the full operation details and stable slice handling in tests.
31
+
32
+ ## [1.0.6] - 2026-06-05
33
+
34
+ ### Added
35
+
36
+ - **Built-in `update` command** — standalone binaries can check GitHub Releases, verify `checksums.txt`, and replace the current executable. Package-manager installs are detected and guided back to the package manager unless `--force` is used.
37
+ - **Global output format control** — `--format json|text|raw` now controls CLI output across commands. JSON is the default for agent-friendly parsing, `text` keeps human-readable tables and prompts, and `raw` is explicitly supported only by commands that can return raw output.
38
+
39
+ ### Changed
40
+
41
+ - **Agent-friendly defaults** — commands now emit stable JSON by default, while `--json` remains a compatibility alias for `--format json`.
42
+ - **Reference output** — `jira-cli reference` now defaults to structured JSON; use `jira-cli --format text reference` for the Markdown command reference.
43
+ - **Output flag rules** — `--compact` and `--fields` are JSON-only, `--quiet` no longer suppresses JSON/raw result bodies, and unsupported `raw` output returns an argument error instead of silently downgrading.
44
+
45
+ ### Fixed
46
+
47
+ - **Structured argument errors** — Cobra argument validation errors now return machine-readable JSON by default instead of plain text.
48
+ - **Clean JSON stdout** — interactive prompts and cancellation/error paths no longer pollute JSON success output.
49
+
10
50
  ## [1.0.5] - 2026-06-02
11
51
 
12
52
  ### Added
@@ -119,7 +159,9 @@ Initial release of jira-cli for Jira Data Center.
119
159
  - SKILL.md with JSON output schemas, error codes, exit codes, and complete flag reference.
120
160
  - GitHub PR template for contributors.
121
161
 
122
- [Unreleased]: https://github.com/fatecannotbealtered/jira-cli/compare/v1.0.5...HEAD
162
+ [Unreleased]: https://github.com/fatecannotbealtered/jira-cli/compare/v1.1.0...HEAD
163
+ [1.1.0]: https://github.com/fatecannotbealtered/jira-cli/compare/v1.0.6...v1.1.0
164
+ [1.0.6]: https://github.com/fatecannotbealtered/jira-cli/compare/v1.0.5...v1.0.6
123
165
  [1.0.5]: https://github.com/fatecannotbealtered/jira-cli/compare/v1.0.4...v1.0.5
124
166
  [1.0.4]: https://github.com/fatecannotbealtered/jira-cli/compare/v1.0.3...v1.0.4
125
167
  [1.0.3]: https://github.com/fatecannotbealtered/jira-cli/compare/v1.0.2...v1.0.3
package/README.md CHANGED
@@ -11,7 +11,7 @@ Full-featured Jira Data Center CLI for humans and AI Agents. Manage issues, spri
11
11
 
12
12
  Built with Go. Single static binary (small dependency footprint via `go.mod`). No separate runtime to install.
13
13
 
14
- [Installation](#installation) · [Authentication](#authentication) · [Commands](#commands) · [JSON Output](#json-output) · [Security](#security) · [Contributing](#contributing) · [Disclaimer](#disclaimer)
14
+ [Installation](#installation) · [Updating](#updating) · [Authentication](#authentication) · [Commands](#commands) · [Output Formats](#output-formats) · [Security](#security) · [Contributing](#contributing) · [Disclaimer](#disclaimer)
15
15
 
16
16
  ## Disclaimer
17
17
 
@@ -22,12 +22,13 @@ This project is shared for **personal learning, research, and everyday productiv
22
22
  | Capability | Description |
23
23
  |---|---|
24
24
  | 🎯 **Complete Coverage** | Issues, Sprints, Boards, Epics, Projects, Users, Filters |
25
- | 🤖 **AI Friendly** | `--json` flat output (token-efficient), `--quiet`, `--dry-run`, `--force`, `--fields`, `--raw` |
25
+ | 🤖 **AI Friendly** | JSON by default, `--format json\|text\|raw`, `--compact`, `--quiet`, `--dry-run`, `--force`, `--fields` |
26
26
  | ⚡ **Single Binary** | Download and run; no JVM/Node required for the CLI itself |
27
27
  | 🔄 **Smart Retry** | Auto-retry on 429 rate limits and 5xx errors with exponential backoff |
28
28
  | 🌈 **Beautiful Output** | Colored tables with CJK character support |
29
29
  | 🔍 **Powerful Search** | Full JQL support with auto-pagination |
30
30
  | 🔧 **Custom Fields** | Set custom fields during create and edit |
31
+ | ⬆️ **Safe Update** | Built-in release checks, checksum verification, package-manager guardrails |
31
32
  | 🔐 **PAT Auth** | Bearer token authentication (Personal Access Token) |
32
33
  | 🌐 **Env Vars** | `JIRA_HOST` and `JIRA_TOKEN` override config file for CI/Agent use |
33
34
  | 📋 **Audit Log** | Automatic JSONL audit trail for all write commands with auto-rotation |
@@ -39,16 +40,17 @@ This project is shared for **personal learning, research, and everyday productiv
39
40
  Copy the block below to your agent (or run it yourself):
40
41
 
41
42
  ```bash
42
- # Please install jira-cli and use it for all Jira DC operations going forward (always pass --json).
43
+ # Please install jira-cli and use it for all Jira DC operations going forward.
44
+ # Machine-readable JSON is the default; use --format text only for human-readable output.
43
45
  # Install CLI (requires curl on PATH — used to download the binary)
44
46
  npm install -g @fatecannotbealtered-/jira-cli
45
47
 
46
48
  # Install CLI Skill (required) — copies into your agent-supported skills directory
47
49
  npx skills add fatecannotbealtered/jira-cli -y -g
48
50
 
49
- # Login and verify
50
- jira-cli login
51
- jira-cli doctor --json
51
+ # Login and verify (interactive login is text mode)
52
+ jira-cli --format text login
53
+ jira-cli doctor
52
54
  ```
53
55
 
54
56
  Optional: `jira-cli install-skill` copies the bundled skill to `~/.openclaw/skills` for OpenClaw-compatible agents.
@@ -63,6 +65,22 @@ go install github.com/fatecannotbealtered/jira-cli/cmd/jira-cli@latest
63
65
 
64
66
  Download from [GitHub Releases](https://github.com/fatecannotbealtered/jira-cli/releases) and add to your PATH.
65
67
 
68
+ ## Updating
69
+
70
+ ```bash
71
+ jira-cli update --check # check latest GitHub Release
72
+ jira-cli update # update a standalone binary
73
+ jira-cli update --version v1.1.0 # install a specific release
74
+ ```
75
+
76
+ `jira-cli update` verifies `checksums.txt` before replacing the current binary. If the CLI was installed through npm, the command will recommend the package-manager path instead:
77
+
78
+ ```bash
79
+ npm install -g @fatecannotbealtered-/jira-cli@latest
80
+ ```
81
+
82
+ Use `--dry-run` to preview and `--force` only when intentionally replacing the binary in place.
83
+
66
84
  ## Authentication
67
85
 
68
86
  jira-cli supports **Jira Data Center** (private deployments) with **Personal Access Token (PAT)** authentication.
@@ -70,7 +88,7 @@ jira-cli supports **Jira Data Center** (private deployments) with **Personal Acc
70
88
  ### Interactive login
71
89
 
72
90
  ```bash
73
- jira-cli login
91
+ jira-cli --format text login
74
92
  # Jira host: https://jira.company.com
75
93
  # Personal Access Token (PAT): ****
76
94
  # ✔ Logged in as John Doe (johndoe)
@@ -92,7 +110,7 @@ Environment variables take precedence over the config file. This is the recommen
92
110
  ```bash
93
111
  export JIRA_HOST=https://jira.company.com
94
112
  export JIRA_TOKEN=<your-personal-access-token>
95
- jira-cli doctor --json # verify authValid is true
113
+ jira-cli doctor # verify .data.config.auth_status is "valid"
96
114
  ```
97
115
 
98
116
  ### Generating a PAT
@@ -111,47 +129,47 @@ jira-cli issue get PROJ-123
111
129
  jira-cli issue list --project PROJ
112
130
  jira-cli issue list --project PROJ --status "In Progress" --assignee me
113
131
 
114
- # Create & Edit
115
- jira-cli issue create --project PROJ --summary "Fix login bug" --type Bug
116
- jira-cli issue create --project PROJ --summary "Sized story" --field "Story Points=5"
117
- jira-cli issue edit PROJ-123 --priority High --assignee me
118
- jira-cli issue edit PROJ-123 --field "Story Points=8" --field "Team=Backend"
119
- jira-cli issue delete PROJ-123 --force # --force skips confirmation prompt
120
- jira-cli issue delete PROJ-123 --dry-run --json # preview delete (no confirmation prompt)
132
+ # Create & Edit (direct human execution uses text mode; JSON automation uses dry-run/confirm)
133
+ jira-cli --format text issue create --project PROJ --summary "Fix login bug" --type Bug
134
+ jira-cli --format text issue create --project PROJ --summary "Sized story" --field "Story Points=5"
135
+ jira-cli --format text issue edit PROJ-123 --priority High --assignee me
136
+ jira-cli --format text issue edit PROJ-123 --field "Story Points=8" --field "Team=Backend"
137
+ jira-cli --format text issue delete PROJ-123 --force # skips text-mode confirmation prompt
138
+ jira-cli issue delete PROJ-123 --dry-run # preview delete and get confirm_token
121
139
 
122
140
  # Clone
123
- jira-cli issue clone PROJ-123
124
- jira-cli issue clone PROJ-123 --summary "New title" --with-links
141
+ jira-cli --format text issue clone PROJ-123
142
+ jira-cli --format text issue clone PROJ-123 --summary "New title" --with-links
125
143
 
126
144
  # Status
127
145
  jira-cli issue transitions PROJ-123 # List available transitions
128
- jira-cli issue transition PROJ-123 "Done" # Status name required as argument
146
+ jira-cli --format text issue transition PROJ-123 "Done" # Status name required as argument
129
147
 
130
148
  # Bulk Transition
131
- jira-cli issue bulk-transition "Done" --issues PROJ-1,PROJ-2,PROJ-3
132
- jira-cli issue bulk-transition "In Progress" --jql "sprint = 10 AND status = 'To Do'"
149
+ jira-cli --format text issue bulk-transition "Done" --issues PROJ-1,PROJ-2,PROJ-3
150
+ jira-cli --format text issue bulk-transition "In Progress" --jql "sprint = 10 AND status = 'To Do'"
133
151
 
134
152
  # Collaboration
135
- jira-cli issue assign PROJ-123 me # Assign to current user
136
- jira-cli issue assign PROJ-123 johndoe # Assign by username (DC uses name, not accountId)
137
- jira-cli issue watch PROJ-123
138
- jira-cli issue vote PROJ-123
153
+ jira-cli --format text issue assign PROJ-123 me # Assign to current user
154
+ jira-cli --format text issue assign PROJ-123 johndoe # Assign by username (DC uses name, not accountId)
155
+ jira-cli --format text issue watch PROJ-123
156
+ jira-cli --format text issue vote PROJ-123
139
157
 
140
158
  # Comments
141
- jira-cli issue comment add PROJ-123 --body "Fixed in PR #42"
159
+ jira-cli --format text issue comment add PROJ-123 --body "Fixed in PR #42"
142
160
  jira-cli issue comment list PROJ-123
143
161
 
144
162
  # Worklogs
145
- jira-cli issue worklog add PROJ-123 --time 2h --comment "Debugging"
163
+ jira-cli --format text issue worklog add PROJ-123 --time 2h --comment "Debugging"
146
164
  jira-cli issue worklog list PROJ-123
147
165
 
148
166
  # Links & Attachments
149
- jira-cli issue link PROJ-123 --to PROJ-456 --type "blocks"
150
- jira-cli issue attach PROJ-123 --file ./screenshot.png
167
+ jira-cli --format text issue link PROJ-123 --to PROJ-456 --type "blocks"
168
+ jira-cli --format text issue attach PROJ-123 --file ./screenshot.png
151
169
  jira-cli issue attachments PROJ-123 # List attachments
152
170
  jira-cli issue attachments PROJ-123 --out ./downloads # Download all attachments
153
171
  jira-cli issue attachments PROJ-123 --out ./downloads --id 4609477 # Download one by ID
154
- jira-cli issue remote-link PROJ-123 --url https://pr.url --title "PR #42"
172
+ jira-cli --format text issue remote-link PROJ-123 --url https://pr.url --title "PR #42"
155
173
  ```
156
174
 
157
175
  ### Search (JQL)
@@ -168,9 +186,9 @@ jira-cli search "project = PROJ" --limit 100 --order-by updated
168
186
  ```bash
169
187
  jira-cli sprint list --board 42
170
188
  jira-cli sprint active --board 42
171
- jira-cli sprint create --board 42 --name "Sprint 5" --start-date 2024-02-01 --end-date 2024-02-14
172
- jira-cli sprint move --sprint 10 --issues PROJ-123,PROJ-124
173
- jira-cli sprint close --sprint 10
189
+ jira-cli --format text sprint create --board 42 --name "Sprint 5" --start-date 2024-02-01 --end-date 2024-02-14
190
+ jira-cli --format text sprint move --sprint 10 --issues PROJ-123,PROJ-124
191
+ jira-cli --format text sprint close --sprint 10
174
192
  jira-cli sprint close --sprint 10 --dry-run # preview without closing
175
193
  ```
176
194
 
@@ -200,65 +218,90 @@ jira-cli user search --query "john"
200
218
  jira-cli user me
201
219
  jira-cli filter list
202
220
  jira-cli filter run <filterId>
203
- jira-cli filter run <filterId> --json --fields key,summary,status
204
- jira-cli filter run <filterId> --json --raw
221
+ jira-cli filter run <filterId> --fields key,summary,status
222
+ jira-cli --format raw filter run <filterId>
205
223
  ```
206
224
 
207
- ## JSON Output
225
+ ## Output Formats
208
226
 
209
- All commands support `--json` for machine-readable output. **Success JSON goes to stdout; error JSON goes to stderr** pipe or capture stdout for data, check `$?` and stderr for failures.
227
+ `jira-cli` defaults to machine-readable JSON, so scripts and AI Agents can omit output flags. Use `--format json|text|raw` to choose the result format:
210
228
 
211
- By default, issue and sprint data is returned in a **flat, token-efficient format** (ideal for AI Agents):
229
+ - `json` is the default. Success and error envelopes both go to stdout; logs, prompts, and warnings go to stderr.
230
+ - `text` is for human-readable summaries, tables, colors, diff/log text, and prompts.
231
+ - `raw` is for unwrapped raw command results where supported. Unsupported commands return an argument error instead of silently downgrading.
232
+
233
+ `--json` remains as a compatibility alias for `--format json`, but new scripts should rely on the default or use `--format json`. `--json` cannot be combined with `--format text` or `--format raw`.
234
+
235
+ `--compact` only affects JSON. `--fields` only works with JSON output. `--quiet` suppresses auxiliary text output only; it does not suppress JSON or raw main results.
236
+
237
+ By default, issue and sprint data is returned in the envelope's `data` field as a **flat, token-efficient JSON format** (ideal for AI Agents):
212
238
 
213
239
  ```bash
214
240
  # Flat JSON (default) — minimal fields, low token cost
215
- jira-cli issue get PROJ-123 --json
216
- jira-cli search "project = PROJ" --json | jq '.issues[].key'
241
+ jira-cli issue get PROJ-123
242
+ jira-cli search "project = PROJ" | jq '.data.issues[].key'
217
243
 
218
- # issue list returns a bare array; search wraps issues in pagination metadata
219
- # filter run with --fields also returns a bare trimmed array
220
- jira-cli issue list --project PROJ --json | jq '.[].key'
221
- jira-cli search "project = PROJ" --json | jq '.issues[].key'
222
- jira-cli filter run 12345 --json --fields key,summary | jq '.[].key'
244
+ # issue list returns an array in .data; search wraps issues in pagination metadata under .data
245
+ # filter run with --fields also returns a trimmed array in .data
246
+ jira-cli issue list --project PROJ | jq '.data[].key'
247
+ jira-cli search "project = PROJ" | jq '.data.issues[].key'
248
+ jira-cli filter run 12345 --fields key,summary | jq '.data[].key'
223
249
 
224
250
  # Trim flat JSON output (issue get / issue list / sprint / filter run)
225
- jira-cli issue get PROJ-123 --json --fields key,summary,status,assignee
251
+ jira-cli issue get PROJ-123 --fields key,summary,status,assignee
226
252
 
227
253
  # search --fields controls which fields Jira fetches (API request), not output trimming
228
- jira-cli search "project = PROJ" --fields summary,status,customfield_10001 --json
254
+ jira-cli search "project = PROJ" --fields summary,status,customfield_10001
229
255
 
230
256
  # Raw Jira API response (full nested structure)
231
- jira-cli issue get PROJ-123 --json --raw
257
+ jira-cli --format raw issue get PROJ-123
258
+
259
+ # Human-readable output
260
+ jira-cli --format text issue get PROJ-123
232
261
 
233
- # Clean output for scripts (suppress all non-JSON noise on stdout)
234
- jira-cli issue get PROJ-123 --json --quiet
262
+ # Compact JSON for logs or pipes
263
+ jira-cli --compact issue get PROJ-123
235
264
 
236
265
  # Preview destructive operations without executing
237
- jira-cli issue delete PROJ-123 --dry-run --json
266
+ jira-cli issue delete PROJ-123 --dry-run
267
+ ```
268
+
269
+ JSON-mode write commands use a two-step confirmation flow:
270
+
271
+ ```bash
272
+ TOKEN=$(jira-cli issue create --project PROJ --summary "Fix login bug" --dry-run --compact | jq -r '.data.confirm_token')
273
+ jira-cli issue create --project PROJ --summary "Fix login bug" --confirm "$TOKEN"
238
274
  ```
239
275
 
240
276
  ### Verify connectivity (`doctor`)
241
277
 
242
- When using `--json`, check the `authValid` field (exit code 3 on auth/config failure):
278
+ With the default JSON output, check `data.config.auth_status` (exit code 4 on auth/config failure):
243
279
 
244
280
  ```bash
245
- jira-cli doctor --json | jq '.authValid' # must be true
281
+ jira-cli doctor | jq -e '.data.config.auth_status == "valid"'
246
282
  ```
247
283
 
248
- Error responses (stderr) include machine-readable error codes and actionable hints:
284
+ Error responses use the same stdout envelope and include machine-readable error codes and retry hints:
249
285
 
250
286
  ```json
251
287
  {
252
- "error": "Jira API error 404: Issue does not exist",
253
- "statusCode": 404,
254
- "errorCode": "NOT_FOUND",
255
- "hint": "Verify the issue key exists and you have permission to view it"
288
+ "ok": false,
289
+ "schema_version": "1.0",
290
+ "error": {
291
+ "code": "E_NOT_FOUND",
292
+ "message": "Jira API error 404: Issue does not exist",
293
+ "details": {
294
+ "status_code": 404,
295
+ "hint": "Verify the resource key/ID exists and you have permission to view it"
296
+ },
297
+ "retryable": false
298
+ }
256
299
  }
257
300
  ```
258
301
 
259
302
  Set `NO_COLOR=1` to disable colored output (useful in CI/CD).
260
303
 
261
- Run `jira-cli reference` to get a complete listing of all commands and flags in structured markdown.
304
+ Run `jira-cli reference` to get a structured JSON listing of all commands and flags. Use `jira-cli --format text reference` for the markdown reference.
262
305
 
263
306
  ## Environment Variables
264
307
 
@@ -286,19 +329,22 @@ Credentials stored at `~/.jira-cli/config.json` (permissions: 0600):
286
329
 
287
330
  | Flag | Description |
288
331
  |---|---|
289
- | `--json` | Output as JSON (flat format by default; use `--raw` for full Jira response) |
332
+ | `--format json\|text\|raw` | Control output format. Default: `json` |
333
+ | `--compact` | Emit compact JSON (only with `--format json`) |
334
+ | `--json` | Compatibility alias for `--format json`; not recommended for new scripts |
290
335
  | `--force` | Skip interactive confirmation prompts |
291
- | `--quiet` | Suppress non-JSON stdout output (for scripts and AI Agents) |
292
- | `--dry-run` | Show what would be done without executing (write commands only) |
336
+ | `--quiet` | Suppress auxiliary text output; does not suppress JSON/raw main results |
337
+ | `--dry-run` | Show what would be done without executing (supported by write/update commands) |
338
+ | `--confirm <token>` | Execute a JSON-mode write command using the token returned by `--dry-run` |
293
339
 
294
340
  ### Per-command flags
295
341
 
296
342
  | Flag | Commands | Description |
297
343
  |---|---|---|
298
- | `--raw` | `issue get`, `issue list`, `search`, `filter run`, `sprint list`, `sprint issues`, `sprint active` | Return raw Jira API response instead of flat format |
299
- | `--fields` | `issue get`, `issue list`, `sprint list`, `sprint issues`, `filter run` | **Output trimming** — include only listed fields in flat JSON (e.g. `--fields key,summary,status`) |
300
- | `--fields` | `search` only | **Jira fetch fields** — comma-separated fields to request from the API (e.g. `--fields summary,status,customfield_10001`); does not trim flat output |
301
- | `--out` | `issue attachments` | Download attachments into this directory instead of listing (default cwd via the dir you pass); with `--json` prints `{id, filename, path, mimeType}` |
344
+ | `--raw` | `issue get`, `issue list`, `search`, `filter run`, `sprint list`, `sprint issues`, `sprint active` | Legacy alias for `--format raw` on commands that support raw output |
345
+ | `--fields` | `issue get`, `issue list`, `sprint list`, `sprint issues`, `filter run` | **JSON output trimming** — include only listed fields in flat JSON (e.g. `--fields key,summary,status`) |
346
+ | `--fields` | `search` only | **Jira fetch fields** — comma-separated fields to request from the API (e.g. `--fields summary,status,customfield_10001`); only valid with JSON output |
347
+ | `--out` | `issue attachments` | Download attachments into this directory instead of listing (default cwd via the dir you pass); JSON output prints `{id, filename, path, mimeType}` |
302
348
  | `--id` | `issue attachments` | With `--out`, download only the attachment with this ID (exit code 4 if not found) |
303
349
 
304
350
  ## Troubleshooting
@@ -306,7 +352,7 @@ Credentials stored at `~/.jira-cli/config.json` (permissions: 0600):
306
352
  | Issue | Solution |
307
353
  |---|---|
308
354
  | npm install fails / curl not found | Ensure `curl` is on PATH (required by npm postinstall to download the binary) |
309
- | Config not found | Run `jira-cli login` or set `JIRA_HOST` and `JIRA_TOKEN` env vars |
355
+ | Config not found | Run `jira-cli --format text login`, `jira-cli login --host <url> --token <pat>`, or set `JIRA_HOST` and `JIRA_TOKEN` env vars |
310
356
  | Authentication failed | Regenerate PAT in your Jira DC profile settings |
311
357
  | Permission denied | Check your PAT scope and project permissions |
312
358
  | Resource not found | Verify the issue key or project key exists |
@@ -317,12 +363,12 @@ Credentials stored at `~/.jira-cli/config.json` (permissions: 0600):
317
363
 
318
364
  - Credentials are stored locally at `~/.jira-cli/config.json` with `0600` file permissions (user-only readable)
319
365
  - Config directory is created with `0700` permissions
320
- - PAT input is hidden during `jira-cli login` (uses terminal secure input)
366
+ - PAT input is hidden during `jira-cli --format text login` (uses terminal secure input)
321
367
  - All communication uses HTTPS (host must start with `https://`)
322
368
  - No credentials are logged or transmitted to third parties
323
369
  - Environment variables `JIRA_HOST` and `JIRA_TOKEN` take precedence over config file
324
370
 
325
- > **AI Agent Note:** This tool can be invoked by AI Agents to automate Jira operations. Use `--force` to skip interactive prompts and `--json` for structured output. Set `JIRA_HOST` and `JIRA_TOKEN` environment variables for non-interactive authentication.
371
+ > **AI Agent Note:** This tool can be invoked by AI Agents to automate Jira operations. Structured JSON is the default; use `--format text` only when human-readable output is needed. Set `JIRA_HOST` and `JIRA_TOKEN` environment variables for non-interactive authentication.
326
372
 
327
373
  For vulnerability reports, see [SECURITY.md](SECURITY.md).
328
374
 
@@ -404,6 +450,7 @@ jira-cli/
404
450
  │ ├── issue_*.go # Issue sub-commands
405
451
  │ ├── flatten.go # Flat JSON output helpers (issues, sprints)
406
452
  │ ├── reference.go # Self-documenting command reference
453
+ │ ├── update.go # GitHub Release self-update
407
454
  │ ├── sprint.go # Sprint management
408
455
  │ ├── board.go # Board operations
409
456
  │ ├── project.go # Project management
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fatecannotbealtered-/jira-cli",
3
- "version": "1.0.5",
3
+ "version": "1.1.0",
4
4
  "description": "Full-featured Jira Data Center CLI for humans and AI Agents — manage issues, sprints, boards, epics, projects, users, and filters from your terminal",
5
5
  "keywords": [
6
6
  "jira",
package/scripts/run.js CHANGED
@@ -8,7 +8,13 @@ const ext = process.platform === "win32" ? ".exe" : "";
8
8
  const bin = path.join(__dirname, "..", "bin", "jira-cli" + ext);
9
9
 
10
10
  try {
11
- execFileSync(bin, process.argv.slice(2), { stdio: "inherit" });
11
+ execFileSync(bin, process.argv.slice(2), {
12
+ stdio: "inherit",
13
+ env: {
14
+ ...process.env,
15
+ JIRA_CLI_INSTALL_METHOD: process.env.JIRA_CLI_INSTALL_METHOD || "npm",
16
+ },
17
+ });
12
18
  } catch (e) {
13
19
  if (e.code === "ENOENT") {
14
20
  console.error("Binary not found. Run 'npm install -g @fatecannotbealtered-/jira-cli' to reinstall.");
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jira-cli
3
- description: Full Jira Data Center control from the terminal. Manage issues, sprints, boards, epics, projects, users, and filters. Use --json flag for machine-readable output when parsing results programmatically.
3
+ description: Full Jira Data Center control from the terminal. Manage issues, sprints, boards, epics, projects, users, and filters. Output is machine-readable JSON by default; use --format text only for human-readable output.
4
4
  metadata: {"openclaw":{"emoji":"🎯","requires":{"bins":["jira-cli"]}}}
5
5
  ---
6
6
 
@@ -9,20 +9,36 @@ metadata: {"openclaw":{"emoji":"🎯","requires":{"bins":["jira-cli"]}}}
9
9
  Jira Data Center CLI for humans and AI Agents. Supports **Jira DC only** (self-hosted), not Jira Cloud.
10
10
 
11
11
  ```bash
12
- # Please install jira-cli and use it for all Jira DC operations going forward (always pass --json).
12
+ # Please install jira-cli and use it for all Jira DC operations going forward.
13
+ # Machine-readable JSON is the default; use --format text only for human-readable output.
13
14
  # Install CLI (requires curl on PATH)
14
15
  npm install -g @fatecannotbealtered-/jira-cli
15
16
 
16
17
  # Install CLI Skill (required) — copies into your agent-supported skills directory
17
18
  npx skills add fatecannotbealtered/jira-cli -y -g
18
19
 
19
- # Login and verify
20
- jira-cli login
21
- jira-cli doctor --json
20
+ # Login and verify (interactive login is text mode)
21
+ jira-cli --format text login
22
+ jira-cli doctor
22
23
  ```
23
24
 
24
25
  Optional: `jira-cli install-skill` → `~/.openclaw/skills`.
25
26
 
27
+ ## Updating
28
+
29
+ ```bash
30
+ jira-cli update --check # Check the latest GitHub Release
31
+ jira-cli update # Update a standalone binary after checksum verification
32
+ ```
33
+
34
+ If the CLI was installed through npm, prefer the package manager instead of in-place replacement:
35
+
36
+ ```bash
37
+ npm install -g @fatecannotbealtered-/jira-cli@latest
38
+ ```
39
+
40
+ Use `--dry-run` to preview. Use `--force` only when the user explicitly wants in-place binary replacement.
41
+
26
42
  ## Prerequisites
27
43
 
28
44
  Before using any command, authenticate with a Jira DC instance. Follow these steps in order:
@@ -31,86 +47,95 @@ Before using any command, authenticate with a Jira DC instance. Follow these ste
31
47
  2. Ask the user for a **Personal Access Token (PAT)**. If they don't have one, guide them:
32
48
  "Log in to your Jira DC → click your profile avatar → Personal Access Tokens → Create token."
33
49
  3. Run `jira-cli login --host <URL> --token <PAT>` to save credentials.
34
- 4. Run `jira-cli doctor --json` to verify connectivity. Check that `authValid` is `true` (exit code 3 on auth/config failure).
50
+ 4. Run `jira-cli doctor` to verify connectivity. Check that `.data.config.auth_status` is `"valid"` (exit code 4 on auth/config failure).
35
51
 
36
52
  **Important:** Credentials are saved locally at `~/.jira-cli/config.json`. Environment variables `JIRA_HOST` and `JIRA_TOKEN` override the config file — use them for CI or when the user prefers not to save credentials.
37
53
 
38
- **Always use `--json` flag when parsing output.** Without it, output is human-formatted and not suitable for programmatic use.
54
+ **Do not add output flags for programmatic parsing.** JSON is the default. Use `--format text` only when the user wants human-readable tables or summaries.
39
55
 
40
- **Stdout vs stderr:** Success JSON is written to **stdout**; error JSON is written to **stderr**. Capture stdout for data; check exit code and stderr for failures.
56
+ **Stdout vs stderr:** Success and error JSON envelopes are written to **stdout** by default. Progress, prompts, warnings, and text-mode errors are written to **stderr**. Capture stdout for data and error envelopes; use exit codes for control flow.
41
57
 
42
58
  ## Safety
43
59
 
44
- - **Do NOT use `--force` on destructive commands unless the user explicitly asks.** Commands like `issue delete` prompt for confirmation by default. Skipping confirmation with `--force` is irreversible.
45
- - **`issue delete --dry-run` skips confirmation** dry-run is evaluated before the confirmation prompt.
46
- - **Use `--dry-run` before write operations** to preview what will happen without executing. Example: `issue create --project PROJ --summary "test" --type Task --dry-run --json`.
60
+ - **Do NOT use `--force` on destructive commands unless the user explicitly asks.** In text mode, commands like `issue delete` prompt for confirmation by default. Skipping confirmation with `--force` is irreversible.
61
+ - **Use `--dry-run` before JSON write operations**, inspect `.data.preview`, then execute the same command with `--confirm <token>` from `.data.confirm_token`.
62
+ - **`issue delete --dry-run` skips confirmation** dry-run is evaluated before any text-mode confirmation prompt.
63
+ - **Use `--dry-run` before write operations** to preview what will happen without executing. Example: `issue create --project PROJ --summary "test" --type Task --dry-run`.
47
64
  - **AI Agents can make mistakes.** Always confirm with the user before executing `issue delete`, `issue bulk-transition`, `sprint close`, or any operation that modifies multiple issues.
48
65
  - All write operations are recorded in `~/.jira-cli/audit/` for traceability.
49
66
 
67
+ JSON write flow:
68
+
69
+ ```bash
70
+ TOKEN=$(jira-cli issue create --project PROJ --summary "Fix login bug" --dry-run --compact | jq -r '.data.confirm_token')
71
+ jira-cli issue create --project PROJ --summary "Fix login bug" --confirm "$TOKEN"
72
+ ```
73
+
50
74
  ## Issue Management
51
75
 
52
76
  ```bash
53
77
  # View issues (flat JSON by default — token-efficient)
54
- jira-cli issue get PROJ-123 --json
55
- jira-cli issue get PROJ-123 --json --fields key,summary,status,assignee # Output trimming (flat JSON)
56
- jira-cli issue get PROJ-123 --json --raw # Full Jira API response
57
- jira-cli issue list --project PROJ --json # Returns bare array of flat issues
58
- jira-cli issue list --project PROJ --json --fields key,summary,status # Trimmed array
78
+ jira-cli issue get PROJ-123
79
+ jira-cli issue get PROJ-123 --fields key,summary,status,assignee # Output trimming (flat JSON)
80
+ jira-cli --format raw issue get PROJ-123 # Full Jira API response
81
+ jira-cli issue list --project PROJ # Returns envelope with flat issue array in .data
82
+ jira-cli issue list --project PROJ --fields key,summary,status # Trimmed array
59
83
 
60
84
  # Create and edit
61
- jira-cli issue create --project PROJ --summary "Fix login bug" --type Bug --json
62
- jira-cli issue create --project PROJ --summary "New feature" --type Story --assignee me --priority High --json
63
- jira-cli issue create --project PROJ --summary "Sized story" --type Story --field "Story Points=5" --json
64
- jira-cli issue edit PROJ-123 --summary "Updated summary" --priority Medium
65
- jira-cli issue edit PROJ-123 --field "Story Points=8" --field "Team=Backend"
66
- jira-cli issue delete PROJ-123 --force # Skip confirmation prompt
67
- jira-cli issue delete PROJ-123 --dry-run --json # Preview delete (no confirmation prompt)
85
+ # For direct human execution, use --format text. For JSON automation, use dry-run/confirm.
86
+ jira-cli --format text issue create --project PROJ --summary "Fix login bug" --type Bug
87
+ jira-cli --format text issue create --project PROJ --summary "New feature" --type Story --assignee me --priority High
88
+ jira-cli --format text issue create --project PROJ --summary "Sized story" --type Story --field "Story Points=5"
89
+ jira-cli --format text issue edit PROJ-123 --summary "Updated summary" --priority Medium
90
+ jira-cli --format text issue edit PROJ-123 --field "Story Points=8" --field "Team=Backend"
91
+ jira-cli --format text issue delete PROJ-123 --force # Skip text-mode confirmation prompt
92
+ jira-cli issue delete PROJ-123 --dry-run # Preview delete and get confirm_token
68
93
 
69
94
  # Clone an issue
70
- jira-cli issue clone PROJ-123 --json # Clone with default summary
71
- jira-cli issue clone PROJ-123 --summary "New title" --json # Clone with custom summary
72
- jira-cli issue clone PROJ-123 --with-links --json # Clone with issue links
95
+ jira-cli --format text issue clone PROJ-123 # Clone with default summary
96
+ jira-cli --format text issue clone PROJ-123 --summary "New title" # Clone with custom summary
97
+ jira-cli --format text issue clone PROJ-123 --with-links # Clone with issue links
73
98
 
74
99
  # Status transitions
75
- jira-cli issue transitions PROJ-123 --json # List available transitions
76
- jira-cli issue transition PROJ-123 "In Progress" # Transition to status (name required)
77
- jira-cli issue transition PROJ-123 "Done" --json
100
+ jira-cli issue transitions PROJ-123 # List available transitions
101
+ jira-cli --format text issue transition PROJ-123 "In Progress" # Transition to status (name required)
102
+ jira-cli --format text issue transition PROJ-123 "Done"
78
103
 
79
104
  # Bulk transition
80
- jira-cli issue bulk-transition "Done" --issues PROJ-1,PROJ-2,PROJ-3 --json
81
- jira-cli issue bulk-transition "In Progress" --jql "project = PROJ AND sprint = 10 AND status = 'To Do'" --json
105
+ jira-cli --format text issue bulk-transition "Done" --issues PROJ-1,PROJ-2,PROJ-3
106
+ jira-cli --format text issue bulk-transition "In Progress" --jql "project = PROJ AND sprint = 10 AND status = 'To Do'"
82
107
 
83
108
  # Assignment and watching
84
- jira-cli issue assign PROJ-123 me # Assign to current user
85
- jira-cli issue assign PROJ-123 johndoe # Assign by username (DC uses name, not accountId)
86
- jira-cli issue unassign PROJ-123
87
- jira-cli issue watch PROJ-123
88
- jira-cli issue unwatch PROJ-123
89
- jira-cli issue watchers PROJ-123 --json
90
- jira-cli issue vote PROJ-123
91
- jira-cli issue unvote PROJ-123
109
+ jira-cli --format text issue assign PROJ-123 me # Assign to current user
110
+ jira-cli --format text issue assign PROJ-123 johndoe # Assign by username (DC uses name, not accountId)
111
+ jira-cli --format text issue unassign PROJ-123
112
+ jira-cli --format text issue watch PROJ-123
113
+ jira-cli --format text issue unwatch PROJ-123
114
+ jira-cli issue watchers PROJ-123
115
+ jira-cli --format text issue vote PROJ-123
116
+ jira-cli --format text issue unvote PROJ-123
92
117
 
93
118
  # Comments
94
- jira-cli issue comment add PROJ-123 --body "Fixed in PR #42" --json
95
- jira-cli issue comment list PROJ-123 --json
96
- jira-cli issue comment delete PROJ-123 --id <commentId>
119
+ jira-cli --format text issue comment add PROJ-123 --body "Fixed in PR #42"
120
+ jira-cli issue comment list PROJ-123
121
+ jira-cli --format text issue comment delete PROJ-123 --id <commentId>
97
122
 
98
123
  # Worklogs
99
- jira-cli issue worklog add PROJ-123 --time 2h --comment "Debugging session" --json
100
- jira-cli issue worklog add PROJ-123 --time 1h30m --started "2024-01-15T10:00:00.000+0000"
101
- jira-cli issue worklog list PROJ-123 --json
124
+ jira-cli --format text issue worklog add PROJ-123 --time 2h --comment "Debugging session"
125
+ jira-cli --format text issue worklog add PROJ-123 --time 1h30m --started "2024-01-15T10:00:00.000+0000"
126
+ jira-cli issue worklog list PROJ-123
102
127
 
103
128
  # Links
104
- jira-cli issue link-types --json # List available link types
105
- jira-cli issue link PROJ-123 --to PROJ-456 --type "blocks"
106
- jira-cli issue unlink <linkId>
107
- jira-cli issue remote-link PROJ-123 --url https://pr.url --title "PR #42"
108
- jira-cli issue remote-links PROJ-123 --json
129
+ jira-cli issue link-types # List available link types
130
+ jira-cli --format text issue link PROJ-123 --to PROJ-456 --type "blocks"
131
+ jira-cli --format text issue unlink <linkId>
132
+ jira-cli --format text issue remote-link PROJ-123 --url https://pr.url --title "PR #42"
133
+ jira-cli issue remote-links PROJ-123
109
134
 
110
135
  # Attachments
111
- jira-cli issue attach PROJ-123 --file ./screenshot.png
112
- jira-cli issue attachments PROJ-123 --json # list metadata (incl. content URL)
113
- jira-cli issue attachments PROJ-123 --out ./dl --json # download all -> [{id,filename,path,mimeType}]
136
+ jira-cli --format text issue attach PROJ-123 --file ./screenshot.png
137
+ jira-cli issue attachments PROJ-123 # list metadata (incl. content URL)
138
+ jira-cli issue attachments PROJ-123 --out ./dl # download all -> [{id,filename,path,mimeType}]
114
139
  jira-cli issue attachments PROJ-123 --out ./dl --id 4609477 # download a single attachment by ID
115
140
  ```
116
141
 
@@ -118,83 +143,83 @@ jira-cli issue attachments PROJ-123 --out ./dl --id 4609477 # download a si
118
143
 
119
144
  ```bash
120
145
  # Basic search
121
- jira-cli search "assignee = currentUser() AND status != Done" --json
122
- jira-cli search "project = PROJ AND sprint in openSprints()" --json
146
+ jira-cli search "assignee = currentUser() AND status != Done"
147
+ jira-cli search "project = PROJ AND sprint in openSprints()"
123
148
 
124
149
  # Advanced options
125
- jira-cli search "project = PROJ" --limit 100 --json
126
- jira-cli search "project = PROJ" --all --json # Fetch ALL results (auto-paginate)
150
+ jira-cli search "project = PROJ" --limit 100
151
+ jira-cli search "project = PROJ" --all # Fetch ALL results (auto-paginate)
127
152
  jira-cli search "project = PROJ" --count # Only show total count
128
- jira-cli search "project = PROJ" --order-by updated --json
129
- jira-cli search "type = Bug AND priority = High" --fields summary,status,customfield_10001 --json # Jira fetch fields (API request)
153
+ jira-cli search "project = PROJ" --order-by updated
154
+ jira-cli search "type = Bug AND priority = High" --fields summary,status,customfield_10001 # Jira fetch fields (API request)
130
155
  ```
131
156
 
132
157
  ## Sprint Management
133
158
 
134
159
  ```bash
135
- jira-cli board list --json # Find board IDs first
136
- jira-cli sprint list --board 42 --json
137
- jira-cli sprint list --board 42 --state active --json
138
- jira-cli sprint active --board 42 --json # Active sprint + issues
139
- jira-cli sprint issues --sprint 10 --json
140
- jira-cli sprint create --board 42 --name "Sprint 5" --start-date 2024-02-01 --end-date 2024-02-14 --json
141
- jira-cli sprint update --sprint 10 --goal "Complete payment refactor"
142
- jira-cli sprint move --sprint 10 --issues PROJ-123,PROJ-124,PROJ-125
143
- jira-cli sprint close --sprint 10 --json
144
- jira-cli sprint close --sprint 10 --dry-run --json # Preview without closing (no confirmation prompt)
160
+ jira-cli board list # Find board IDs first
161
+ jira-cli sprint list --board 42
162
+ jira-cli sprint list --board 42 --state active
163
+ jira-cli sprint active --board 42 # Active sprint + issues
164
+ jira-cli sprint issues --sprint 10
165
+ jira-cli --format text sprint create --board 42 --name "Sprint 5" --start-date 2024-02-01 --end-date 2024-02-14
166
+ jira-cli --format text sprint update --sprint 10 --goal "Complete payment refactor"
167
+ jira-cli --format text sprint move --sprint 10 --issues PROJ-123,PROJ-124,PROJ-125
168
+ jira-cli --format text sprint close --sprint 10
169
+ jira-cli sprint close --sprint 10 --dry-run # Preview without closing (no confirmation prompt)
145
170
  ```
146
171
 
147
172
  ## Board & Backlog
148
173
 
149
174
  ```bash
150
- jira-cli board list --json
151
- jira-cli board list --project PROJ --type scrum --json
152
- jira-cli board get --board 42 --json
153
- jira-cli board backlog --board 42 --json
154
- jira-cli board epics --board 42 --json
155
- jira-cli board sprints --board 42 --state active --json
175
+ jira-cli board list
176
+ jira-cli board list --project PROJ --type scrum
177
+ jira-cli board get --board 42
178
+ jira-cli board backlog --board 42
179
+ jira-cli board epics --board 42
180
+ jira-cli board sprints --board 42 --state active
156
181
  ```
157
182
 
158
183
  ## Epic Management
159
184
 
160
185
  ```bash
161
- jira-cli epic list --board 42 --json
162
- jira-cli epic list --board 42 --done --json # Completed epics only
163
- jira-cli epic issues PROJ-1 --board 42 --json
186
+ jira-cli epic list --board 42
187
+ jira-cli epic list --board 42 --done # Completed epics only
188
+ jira-cli epic issues PROJ-1 --board 42
164
189
  ```
165
190
 
166
191
  ## Project Management
167
192
 
168
193
  ```bash
169
- jira-cli project list --json
170
- jira-cli project list --type software --json
171
- jira-cli project get PROJ --json
172
- jira-cli project components PROJ --json
173
- jira-cli project versions PROJ --json
174
- jira-cli project versions PROJ --unreleased --json
175
- jira-cli project issue-types PROJ --json
176
- jira-cli project fields --json # List all fields (system + custom)
177
- jira-cli project fields --custom --json # List custom fields only
194
+ jira-cli project list
195
+ jira-cli project list --type software
196
+ jira-cli project get PROJ
197
+ jira-cli project components PROJ
198
+ jira-cli project versions PROJ
199
+ jira-cli project versions PROJ --unreleased
200
+ jira-cli project issue-types PROJ
201
+ jira-cli project fields # List all fields (system + custom)
202
+ jira-cli project fields --custom # List custom fields only
178
203
  ```
179
204
 
180
205
  ## User Search
181
206
 
182
207
  ```bash
183
- jira-cli user me --json # Current user info
184
- jira-cli user search --query "john" --json
185
- jira-cli user search --query "john" --assignable --project PROJ --json
208
+ jira-cli user me # Current user info
209
+ jira-cli user search --query "john"
210
+ jira-cli user search --query "john" --assignable --project PROJ
186
211
  ```
187
212
 
188
213
  ## Filters
189
214
 
190
215
  ```bash
191
- jira-cli filter list --json
192
- jira-cli filter get <filterId> --json
193
- jira-cli filter create --name "My Bugs" --jql "assignee = me AND type = Bug" --json
194
- jira-cli filter run <filterId> --json
195
- jira-cli filter run <filterId> --json --fields key,summary,status # Output trimming
196
- jira-cli filter run <filterId> --json --raw # Raw Jira search response
197
- jira-cli filter delete <filterId>
216
+ jira-cli filter list
217
+ jira-cli filter get <filterId>
218
+ jira-cli --format text filter create --name "My Bugs" --jql "assignee = me AND type = Bug"
219
+ jira-cli filter run <filterId>
220
+ jira-cli filter run <filterId> --fields key,summary,status # Output trimming
221
+ jira-cli --format raw filter run <filterId> # Raw Jira search response
222
+ jira-cli --format text filter delete <filterId>
198
223
  ```
199
224
 
200
225
  ## Workflow Examples
@@ -202,57 +227,61 @@ jira-cli filter delete <filterId>
202
227
  ### Find and update an issue
203
228
  ```bash
204
229
  # 1. Search for issues
205
- jira-cli search "project = PROJ AND assignee = me AND status = 'In Progress'" --json
230
+ jira-cli search "project = PROJ AND assignee = me AND status = 'In Progress'"
206
231
 
207
232
  # 2. Get issue details
208
- jira-cli issue get PROJ-123 --json
233
+ jira-cli issue get PROJ-123
209
234
 
210
235
  # 3. Check available transitions
211
- jira-cli issue transitions PROJ-123 --json
236
+ jira-cli issue transitions PROJ-123
212
237
 
213
238
  # 4. Transition to Done
214
- jira-cli issue transition PROJ-123 "Done"
239
+ jira-cli --format text issue transition PROJ-123 "Done"
215
240
 
216
241
  # 5. Add a comment
217
- jira-cli issue comment add PROJ-123 --body "Completed and deployed to staging"
242
+ jira-cli --format text issue comment add PROJ-123 --body "Completed and deployed to staging"
218
243
  ```
219
244
 
220
245
  ### Sprint planning workflow
221
246
  ```bash
222
247
  # 1. Find the board
223
- jira-cli board list --json
248
+ jira-cli board list
224
249
 
225
250
  # 2. Check active sprint
226
- jira-cli sprint active --board 42 --json
251
+ jira-cli sprint active --board 42
227
252
 
228
253
  # 3. View backlog
229
- jira-cli board backlog --board 42 --json
254
+ jira-cli board backlog --board 42
230
255
 
231
256
  # 4. Create next sprint
232
- jira-cli sprint create --board 42 --name "Sprint 6" --start-date 2024-02-15 --end-date 2024-02-28 --json
257
+ jira-cli --format text sprint create --board 42 --name "Sprint 6" --start-date 2024-02-15 --end-date 2024-02-28
233
258
 
234
259
  # 5. Move issues to sprint
235
- jira-cli sprint move --sprint 11 --issues PROJ-200,PROJ-201,PROJ-202
260
+ jira-cli --format text sprint move --sprint 11 --issues PROJ-200,PROJ-201,PROJ-202
236
261
  ```
237
262
 
238
263
  ## Guardrails
239
264
 
240
- - Always run `jira-cli doctor --json` and verify **`authValid` is `true`** before bulk operations (exit code 3 on failure)
241
- - `issue delete` requires typing the issue key to confirm. Use `--force` to skip confirmation in automated workflows; `--dry-run` skips confirmation
265
+ - Always run `jira-cli doctor` and verify **`.data.config.auth_status == "valid"`** before bulk operations (exit code 4 on auth/config failure)
266
+ - In JSON mode, write commands require `--dry-run` followed by `--confirm <token>` unless the command explicitly documents otherwise
267
+ - In text mode, `issue delete` requires typing the issue key to confirm. Use `--force` only when the user explicitly asked to skip that prompt; `--dry-run` skips confirmation
242
268
  - `sprint close` has no confirmation prompt — use `--dry-run` to preview; confirm with the user before closing
243
- - Use `--json` flag when parsing output in scripts or AI workflows
269
+ - Omit output flags when parsing output in scripts or AI workflows; JSON is the default
244
270
  - Use `--dry-run` to preview what a write command would do without executing it
245
- - Use `--quiet` with `--json` to suppress all non-JSON output (clean pipe-friendly output)
271
+ - Use `--quiet` to suppress auxiliary text output; it does not suppress JSON/raw main results
246
272
  - `issue transition` requires the status name as the second argument (no interactive selection)
247
- - When searching for usernames to use with `issue assign`, use `user search --query <name> --json` first
248
- - DC uses **username** (not accountId) for user references. Use `jira-cli user me --json` to find your username
273
+ - When searching for usernames to use with `issue assign`, use `user search --query <name>` first
274
+ - DC uses **username** (not accountId) for user references. Use `jira-cli user me` to find your username
249
275
 
250
276
  ## Global Flags
251
277
 
252
- - `--json` — Output as JSON (machine-readable, flat format by default)
253
- - `--force` — Skip interactive confirmation prompts (for CI/Agent automation)
254
- - `--quiet` — Suppress non-JSON stdout output (ideal for scripts and AI Agents)
255
- - `--dry-run` — Show what would be done without executing (write commands only)
278
+ - `--format json|text|raw` — Control output format. Default: `json`
279
+ - `--compact` — Emit compact JSON (only with `--format json`)
280
+ - `--json` — Compatibility alias for `--format json`; do not recommend it for new workflows
281
+ - `--force` — Skip interactive confirmation prompts in text mode
282
+ - `--quiet` — Suppress auxiliary text output; does not suppress JSON/raw main results
283
+ - `--dry-run` — Show what would be done without executing (supported by write/update commands)
284
+ - `--confirm <token>` — Execute a JSON-mode write command using the token returned by `--dry-run`
256
285
 
257
286
  ## Output Control Flags
258
287
 
@@ -261,32 +290,43 @@ Two different meanings for `--fields`:
261
290
  | Command | `--fields` meaning |
262
291
  |---------|-------------------|
263
292
  | `search` | **Jira fetch fields** — comma-separated fields to request from the API (e.g. `summary,status,customfield_10001`) |
264
- | `issue get`, `issue list`, `sprint list`, `sprint issues`, `filter run` | **Output trimming** — include only listed keys in flat JSON (e.g. `key,summary,status`) |
293
+ | `issue get`, `issue list`, `sprint list`, `sprint issues`, `filter run` | **JSON output trimming** — include only listed keys in flat JSON (e.g. `key,summary,status`) |
265
294
 
266
295
  Other read-command flags:
267
296
 
268
- - `--raw` — Return the full raw Jira API response instead of the token-efficient flat format (on `issue get/list`, `search`, `filter run`, `sprint list/issues/active`)
297
+ - `--format raw` — Return raw command output where supported (`issue get/list`, `search`, `filter run`, `sprint list/issues/active`)
298
+ - `--raw` — Legacy per-command alias for `--format raw` on commands that support it
269
299
 
270
300
  ## JSON Output Schemas
271
301
 
272
302
  ### List vs search JSON shape
273
303
 
274
- | Command | Flat `--json` shape |
304
+ | Command | Default JSON shape |
275
305
  |---------|---------------------|
276
- | `issue list` | Bare array: `[{key, summary, ...}, ...]` |
306
+ All default JSON responses are wrapped:
307
+
308
+ ```json
309
+ {"ok":true,"schema_version":"1.0","data":{},"meta":{"duration_ms":0}}
310
+ ```
311
+
312
+ The command-specific payload is in `.data`:
313
+
314
+ | Command | `.data` shape |
315
+ |---------|---------------|
316
+ | `issue list` | Array: `[{key, summary, ...}, ...]` |
277
317
  | `search`, `filter run` (default) | Object with pagination: `{total, startAt, maxResults, issues: [...]}` |
278
- | `filter run --fields ...` | Bare trimmed array (like `issue list --fields`) |
318
+ | `filter run --fields ...` | Trimmed array (like `issue list --fields`) |
279
319
  | `issue get` | Single flat issue object |
280
320
 
281
321
  **jq examples:**
282
322
 
283
323
  ```bash
284
- jira-cli issue list --project PROJ --json | jq '.[].key'
285
- jira-cli search "project = PROJ" --json | jq '.issues[].key'
286
- jira-cli filter run 12345 --json | jq '.issues[].status'
324
+ jira-cli issue list --project PROJ | jq '.data[].key'
325
+ jira-cli search "project = PROJ" | jq '.data.issues[].key'
326
+ jira-cli filter run 12345 | jq '.data.issues[].status'
287
327
  ```
288
328
 
289
- ### Flat Issue (default with --json)
329
+ ### Flat Issue (`.data` in default JSON)
290
330
 
291
331
  ```json
292
332
  {
@@ -305,7 +345,7 @@ jira-cli filter run 12345 --json | jq '.issues[].status'
305
345
  }
306
346
  ```
307
347
 
308
- ### Flat Sprint
348
+ ### Flat Sprint (`.data` in default JSON)
309
349
 
310
350
  ```json
311
351
  {
@@ -318,40 +358,52 @@ jira-cli filter run 12345 --json | jq '.issues[].status'
318
358
  }
319
359
  ```
320
360
 
321
- ### Error Response (with --json, written to stderr)
361
+ ### Error Response (default JSON, written to stdout)
322
362
 
323
363
  ```json
324
364
  {
325
- "error": "Jira API error 404: Issue does not exist",
326
- "statusCode": 404,
327
- "errorCode": "NOT_FOUND",
328
- "hint": "Verify the issue key exists and you have permission to view it"
365
+ "ok": false,
366
+ "schema_version": "1.0",
367
+ "error": {
368
+ "code": "E_NOT_FOUND",
369
+ "message": "Jira API error 404: Issue does not exist",
370
+ "details": {
371
+ "status_code": 404,
372
+ "hint": "Verify the resource key/ID exists and you have permission to view it"
373
+ },
374
+ "retryable": false
375
+ }
329
376
  }
330
377
  ```
331
378
 
332
379
  ### Error Codes
333
380
 
334
- | Code | Status | Hint |
335
- |------|--------|------|
336
- | `AUTH_REQUIRED` | 401 | Run `jira-cli login` or set JIRA_HOST and JIRA_TOKEN |
337
- | `FORBIDDEN` | 403 | Check your PAT scope and project permissions |
338
- | `NOT_FOUND` | 404 | Verify the resource key/ID exists |
339
- | `RATE_LIMITED` | 429 | Wait and retry; reduce request frequency |
340
- | `SERVER_ERROR` | 5xx | Jira server error; retry later |
341
- | `NETWORK_ERROR` | — | Check host URL and network connectivity |
342
- | `CONFIG_ERROR` | — | Run `jira-cli login` or set env vars |
381
+ | Code | Status | Retryable | Hint |
382
+ |------|--------|-----------|------|
383
+ | `E_AUTH_REQUIRED` | 401 | false | Run `jira-cli login --host <url> --token <pat>` or set env vars |
384
+ | `E_FORBIDDEN` | 403 | false | Check your PAT scope and project permissions |
385
+ | `E_NOT_FOUND` | 404 | false | Verify the resource key/ID exists |
386
+ | `E_RATE_LIMITED` | 429 | true | Wait and retry with backoff |
387
+ | `E_SERVER` | 5xx | true | Jira server error; retry later |
388
+ | `E_NETWORK` | — | true | Check host URL and network connectivity |
389
+ | `E_CONFIG` | — | false | Run `jira-cli login --host <url> --token <pat>` or set env vars |
390
+ | `E_CONFIRM_REQUIRED` | — | false | Run the same write command with `--dry-run`, then retry with `--confirm <token>` |
391
+ | `E_CONFLICT` | — | false | Re-run `--dry-run`; the token no longer matches the operation |
392
+ | `E_TIMEOUT` | 408 | true | Retry with backoff |
343
393
 
344
394
  ### Exit Codes
345
395
 
346
396
  | Code | Meaning |
347
397
  |------|---------|
348
398
  | 0 | Success |
399
+ | 1 | Generic error |
349
400
  | 2 | Bad arguments |
350
- | 3 | Authentication error |
351
- | 4 | Resource not found |
352
- | 5 | Forbidden |
353
- | 6 | Rate limited |
354
- | 7 | Network/server error |
401
+ | 3 | Resource not found |
402
+ | 4 | Authentication or permission error |
403
+ | 5 | Confirmation token required |
404
+ | 6 | Conflict / stale confirmation token |
405
+ | 7 | Retryable transient error |
406
+ | 8 | Timeout |
355
407
 
356
408
  ## Audit Logging
357
409
 
@@ -365,5 +417,7 @@ All write commands are automatically logged to `~/.jira-cli/audit/` in JSONL for
365
417
  ## Self-Description
366
418
 
367
419
  ```bash
368
- jira-cli reference # Print all commands, subcommands, and flags in structured markdown
420
+ jira-cli reference # Structured JSON command reference
421
+ jira-cli context # Runtime, config, and credential status
422
+ jira-cli doctor # Environment and connectivity checks
369
423
  ```