@fatecannotbealtered-/jira-cli 1.0.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 +43 -0
- package/CONTRIBUTING.md +56 -0
- package/LICENSE +21 -0
- package/README.md +397 -0
- package/SECURITY.md +28 -0
- package/package.json +51 -0
- package/scripts/install.js +136 -0
- package/scripts/run.js +17 -0
- package/skills/jira-cli/SKILL.md +323 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [1.0.0] - 2026-05-03
|
|
11
|
+
|
|
12
|
+
Initial release of jira-cli for Jira Data Center.
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- **Jira Data Center only**: Bearer PAT authentication, DC `name`-based user references, `/rest/api/2/` exclusively.
|
|
17
|
+
- **Complete coverage**: issues, sprints, boards, epics, projects, users, filters — CRUD + advanced operations.
|
|
18
|
+
- **AI Agent friendly**:
|
|
19
|
+
- `--json` outputs token-efficient flat format by default; `--raw` returns full Jira API response.
|
|
20
|
+
- `--fields key,summary,status` to output only specified fields.
|
|
21
|
+
- `--quiet` suppresses all non-JSON stdout (clean pipe output).
|
|
22
|
+
- `--dry-run` on all write commands — previews without executing.
|
|
23
|
+
- `--force` skips interactive confirmation prompts.
|
|
24
|
+
- Machine-readable error codes (`errorCode`) and actionable hints (`hint`) in JSON error responses.
|
|
25
|
+
- Semantic exit codes: 0=OK, 2=bad args, 3=auth, 4=not found, 5=forbidden, 6=rate limited, 7=network.
|
|
26
|
+
- `reference` command: structured markdown listing of all commands and flags for AI self-discovery.
|
|
27
|
+
- **Smart retry**: automatic exponential backoff on 429 rate limits and 5xx errors.
|
|
28
|
+
- **Beautiful output**: colored tables with CJK character width support.
|
|
29
|
+
- **Custom fields**: set custom fields during create and edit via `--field "Name=Value"`.
|
|
30
|
+
- **Environment variables**: `JIRA_HOST` and `JIRA_TOKEN` override config file for CI/Agent use.
|
|
31
|
+
- **npm distribution**: `npm install -g @fatecannotbealtered-/jira-cli` with bundled AI Agent Skill.
|
|
32
|
+
- **Cross-platform**: Linux, macOS, Windows (x64 + arm64) via GoReleaser.
|
|
33
|
+
- **E2E test scripts**: Comprehensive PowerShell E2E script (`scripts/e2e-full.ps1`) covering all 55+ commands against a real Jira DC instance, with CSV report output and read-only mode.
|
|
34
|
+
- **Audit logging**: Automatic JSONL audit trail for all write commands (`~/.jira-cli/audit/`), with monthly file rotation and configurable retention (default 3 months). Disable with `JIRA_NO_AUDIT=1`.
|
|
35
|
+
|
|
36
|
+
### Documentation
|
|
37
|
+
|
|
38
|
+
- Bilingual README (English + Chinese) with CI/Report Card/License/npm badges.
|
|
39
|
+
- SKILL.md with JSON output schemas, error codes, exit codes, and complete flag reference.
|
|
40
|
+
- GitHub PR template for contributors.
|
|
41
|
+
|
|
42
|
+
[Unreleased]: https://github.com/fatecannotbealtered/jira-cli/compare/v1.0.0...HEAD
|
|
43
|
+
[1.0.0]: https://github.com/fatecannotbealtered/jira-cli/releases/tag/v1.0.0
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thank you for improving jira-cli. This document describes how to build, test, and submit changes.
|
|
4
|
+
|
|
5
|
+
**Note:** This is a side project shared for learning and personal use; maintainers do not offer commercial support or production guarantees�see the readme disclaimer.
|
|
6
|
+
|
|
7
|
+
## Development setup
|
|
8
|
+
|
|
9
|
+
- Go **1.23+** (see `go.mod`)
|
|
10
|
+
- Optional: **Node.js 16+** if you work on npm install scripts
|
|
11
|
+
- Optional: **golangci-lint** (CI runs it on Linux)
|
|
12
|
+
|
|
13
|
+
Clone and verify:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
git clone https://github.com/fatecannotbealtered/jira-cli.git
|
|
17
|
+
cd jira-cli
|
|
18
|
+
go mod download
|
|
19
|
+
go test ./...
|
|
20
|
+
go build -o bin/jira-cli ./cmd/jira-cli
|
|
21
|
+
./bin/jira-cli --help
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
If `go mod download` is slow, try a regional proxy, for example:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Example (China)
|
|
28
|
+
set GOPROXY=https://goproxy.cn,direct
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Commands
|
|
32
|
+
|
|
33
|
+
| Goal | Command |
|
|
34
|
+
|------|---------|
|
|
35
|
+
| Run tests (race) | `go test -race ./...` |
|
|
36
|
+
| Format | `gofmt -w .` |
|
|
37
|
+
| Vet | `go vet ./...` |
|
|
38
|
+
| Lint | `golangci-lint run ./...` (or `make lint` on Unix) |
|
|
39
|
+
| Build with version | `make build` (Unix) or `go build -ldflags "-s -w -X github.com/fatecannotbealtered/jira-cli/cmd.version=dev" -o bin/jira-cli.exe ./cmd/jira-cli` (Windows) |
|
|
40
|
+
|
|
41
|
+
CI mirrors `.github/workflows/ci.yml`: tidy modules, `gofmt` check (Linux), golangci-lint, `go vet`, build, `go test -race`, and a `--help` smoke test.
|
|
42
|
+
|
|
43
|
+
## Pull requests
|
|
44
|
+
|
|
45
|
+
1. **One logical change per PR** when possible.
|
|
46
|
+
2. **Tests**: add or update tests for behavior changes in `internal/` or stable CLI contracts.
|
|
47
|
+
3. **Docs**: update `README.md` / `README_zh.md` if user-facing flags or flows change; add a line to `CHANGELOG.md` under *Unreleased*.
|
|
48
|
+
4. **Commits**: clear messages; no secrets or real tokens in code or docs.
|
|
49
|
+
|
|
50
|
+
## AI Agent skill bundle
|
|
51
|
+
|
|
52
|
+
Bundled skills live under `skills/`. After editing, run `jira-cli install-skill` from a built binary (or from repo root with `./skills`) to confirm files copy correctly. npm installs place the binary under `bin/` and skills under `../skills` relative to the binary; the CLI resolves both layouts.
|
|
53
|
+
|
|
54
|
+
## Security
|
|
55
|
+
|
|
56
|
+
Do not open public issues for undisclosed security vulnerabilities. See [SECURITY.md](SECURITY.md).
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 fatecannotbealtered
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
# jira-cli
|
|
2
|
+
|
|
3
|
+
[](https://github.com/fatecannotbealtered/jira-cli/actions/workflows/ci.yml)
|
|
4
|
+
[](https://goreportcard.com/report/github.com/fatecannotbealtered/jira-cli)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://www.npmjs.com/package/@fatecannotbealtered-/jira-cli)
|
|
7
|
+
|
|
8
|
+
English | [中文](README_zh.md)
|
|
9
|
+
|
|
10
|
+
Full-featured Jira Data Center CLI for humans and AI Agents. Manage issues, sprints, boards, epics, projects, users, and filters — all from your terminal.
|
|
11
|
+
|
|
12
|
+
Built with Go. Single static binary (small dependency footprint via `go.mod`). No separate runtime to install.
|
|
13
|
+
|
|
14
|
+
[Installation](#installation) · [Authentication](#authentication) · [Commands](#commands) · [JSON Output](#json-output) · [Security](#security) · [Contributing](#contributing) · [Disclaimer](#disclaimer)
|
|
15
|
+
|
|
16
|
+
## Disclaimer
|
|
17
|
+
|
|
18
|
+
This project is shared for **personal learning, research, and everyday productivity**—not as a product with SLAs. The maintainers do not offer commercial support or make any **fitness-for-production** promise. If you use it at work, that is your call: follow your org's rules. Software is provided "as is," without warranty of any kind.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
| Capability | Description |
|
|
23
|
+
|---|---|
|
|
24
|
+
| 🎯 **Complete Coverage** | Issues, Sprints, Boards, Epics, Projects, Users, Filters |
|
|
25
|
+
| 🤖 **AI Friendly** | `--json` flat output (token-efficient), `--quiet`, `--dry-run`, `--force`, `--fields`, `--raw` |
|
|
26
|
+
| ⚡ **Single Binary** | Download and run; no JVM/Node required for the CLI itself |
|
|
27
|
+
| 🔄 **Smart Retry** | Auto-retry on 429 rate limits and 5xx errors with exponential backoff |
|
|
28
|
+
| 🌈 **Beautiful Output** | Colored tables with CJK character support |
|
|
29
|
+
| 🔍 **Powerful Search** | Full JQL support with auto-pagination |
|
|
30
|
+
| 🔧 **Custom Fields** | Set custom fields during create and edit |
|
|
31
|
+
| 🔐 **PAT Auth** | Bearer token authentication (Personal Access Token) |
|
|
32
|
+
| 🌐 **Env Vars** | `JIRA_HOST` and `JIRA_TOKEN` override config file for CI/Agent use |
|
|
33
|
+
| 📋 **Audit Log** | Automatic JSONL audit trail for all write commands with auto-rotation |
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
### Quick start
|
|
38
|
+
|
|
39
|
+
Recommended flow: install the CLI from npm, then install the AI Agent Skill with `npx skills add`.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Install CLI
|
|
43
|
+
npm install -g @fatecannotbealtered-/jira-cli
|
|
44
|
+
|
|
45
|
+
# Install CLI Skill
|
|
46
|
+
npx skills add fatecannotbealtered/jira-cli -y -g
|
|
47
|
+
|
|
48
|
+
# Login and verify
|
|
49
|
+
jira-cli login
|
|
50
|
+
jira-cli doctor
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The CLI package provides the `jira-cli` binary; the Skill package teaches compatible AI coding assistants how to use it safely. If you are an AI Agent helping a user set this up, run the same steps and ask the user to complete any interactive browser or terminal prompts.
|
|
54
|
+
|
|
55
|
+
### Alternative: Go install
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
go install github.com/fatecannotbealtered/jira-cli/cmd/jira-cli@latest
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Alternative: Download binary
|
|
62
|
+
|
|
63
|
+
Download from [GitHub Releases](https://github.com/fatecannotbealtered/jira-cli/releases) and add to your PATH.
|
|
64
|
+
|
|
65
|
+
## Authentication
|
|
66
|
+
|
|
67
|
+
jira-cli supports **Jira Data Center** (private deployments) with **Personal Access Token (PAT)** authentication.
|
|
68
|
+
|
|
69
|
+
### Interactive login
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
jira-cli login
|
|
73
|
+
# Jira host: https://jira.company.com
|
|
74
|
+
# Personal Access Token (PAT): ****
|
|
75
|
+
# ✔ Logged in as John Doe (johndoe)
|
|
76
|
+
|
|
77
|
+
jira-cli doctor # Verify connectivity
|
|
78
|
+
jira-cli logout # Remove credentials
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Non-interactive login (CI / AI Agent)
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
jira-cli login --host https://jira.company.com --token <PAT>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Environment variables
|
|
88
|
+
|
|
89
|
+
Environment variables take precedence over the config file. This is the recommended approach for CI pipelines and AI Agents:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
export JIRA_HOST=https://jira.company.com
|
|
93
|
+
export JIRA_TOKEN=<your-personal-access-token>
|
|
94
|
+
jira-cli doctor --json
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Generating a PAT
|
|
98
|
+
|
|
99
|
+
1. Log into your Jira Data Center instance
|
|
100
|
+
2. Go to **Profile** → **Personal Access Tokens**
|
|
101
|
+
3. Create a new token with appropriate permissions
|
|
102
|
+
|
|
103
|
+
## Commands
|
|
104
|
+
|
|
105
|
+
### Issue Management
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# View
|
|
109
|
+
jira-cli issue get PROJ-123
|
|
110
|
+
jira-cli issue list --project PROJ
|
|
111
|
+
jira-cli issue list --project PROJ --status "In Progress" --assignee me
|
|
112
|
+
|
|
113
|
+
# Create & Edit
|
|
114
|
+
jira-cli issue create --project PROJ --summary "Fix login bug" --type Bug
|
|
115
|
+
jira-cli issue create --project PROJ --summary "Sized story" --field "Story Points=5"
|
|
116
|
+
jira-cli issue edit PROJ-123 --priority High --assignee me
|
|
117
|
+
jira-cli issue edit PROJ-123 --field "Story Points=8" --field "Team=Backend"
|
|
118
|
+
jira-cli issue delete PROJ-123 --force # --force skips confirmation
|
|
119
|
+
|
|
120
|
+
# Clone
|
|
121
|
+
jira-cli issue clone PROJ-123
|
|
122
|
+
jira-cli issue clone PROJ-123 --summary "New title" --with-links
|
|
123
|
+
|
|
124
|
+
# Status
|
|
125
|
+
jira-cli issue transitions PROJ-123 # List available transitions
|
|
126
|
+
jira-cli issue transition PROJ-123 "Done" # Status name required as argument
|
|
127
|
+
|
|
128
|
+
# Bulk Transition
|
|
129
|
+
jira-cli issue bulk-transition "Done" --issues PROJ-1,PROJ-2,PROJ-3
|
|
130
|
+
jira-cli issue bulk-transition "In Progress" --jql "sprint = 10 AND status = 'To Do'"
|
|
131
|
+
|
|
132
|
+
# Collaboration
|
|
133
|
+
jira-cli issue assign PROJ-123 me # Assign to current user
|
|
134
|
+
jira-cli issue assign PROJ-123 johndoe # Assign by username (DC uses name, not accountId)
|
|
135
|
+
jira-cli issue watch PROJ-123
|
|
136
|
+
jira-cli issue vote PROJ-123
|
|
137
|
+
|
|
138
|
+
# Comments
|
|
139
|
+
jira-cli issue comment add PROJ-123 --body "Fixed in PR #42"
|
|
140
|
+
jira-cli issue comment list PROJ-123
|
|
141
|
+
|
|
142
|
+
# Worklogs
|
|
143
|
+
jira-cli issue worklog add PROJ-123 --time 2h --comment "Debugging"
|
|
144
|
+
jira-cli issue worklog list PROJ-123
|
|
145
|
+
|
|
146
|
+
# Links & Attachments
|
|
147
|
+
jira-cli issue link PROJ-123 --to PROJ-456 --type "blocks"
|
|
148
|
+
jira-cli issue attach PROJ-123 --file ./screenshot.png
|
|
149
|
+
jira-cli issue remote-link PROJ-123 --url https://pr.url --title "PR #42"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Search (JQL)
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
jira-cli search "assignee = currentUser() AND status != Done"
|
|
156
|
+
jira-cli search "project = PROJ AND sprint in openSprints()" --all
|
|
157
|
+
jira-cli search "type = Bug AND priority = High" --count
|
|
158
|
+
jira-cli search "project = PROJ" --limit 100 --order-by updated
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Sprint Management
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
jira-cli sprint list --board 42
|
|
165
|
+
jira-cli sprint active --board 42
|
|
166
|
+
jira-cli sprint create --board 42 --name "Sprint 5" --start-date 2024-02-01 --end-date 2024-02-14
|
|
167
|
+
jira-cli sprint move --sprint 10 --issues PROJ-123,PROJ-124
|
|
168
|
+
jira-cli sprint close --sprint 10 --force
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Board & Backlog
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
jira-cli board list
|
|
175
|
+
jira-cli board backlog --board 42
|
|
176
|
+
jira-cli board epics --board 42
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Projects, Users & Filters
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
jira-cli project list
|
|
183
|
+
jira-cli project versions PROJ --unreleased
|
|
184
|
+
jira-cli project fields --custom # List custom fields
|
|
185
|
+
jira-cli user search --query "john"
|
|
186
|
+
jira-cli user me
|
|
187
|
+
jira-cli filter list
|
|
188
|
+
jira-cli filter run <filterId>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## JSON Output
|
|
192
|
+
|
|
193
|
+
All commands support `--json` for machine-readable output. By default, issue and sprint data is returned in a **flat, token-efficient format** (ideal for AI Agents):
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# Flat JSON (default) — minimal fields, low token cost
|
|
197
|
+
jira-cli issue get PROJ-123 --json
|
|
198
|
+
jira-cli search "project = PROJ" --json | jq '.issues[].key'
|
|
199
|
+
|
|
200
|
+
# Select only the fields you need
|
|
201
|
+
jira-cli issue get PROJ-123 --json --fields key,summary,status,assignee
|
|
202
|
+
|
|
203
|
+
# Raw Jira API response (full nested structure)
|
|
204
|
+
jira-cli issue get PROJ-123 --json --raw
|
|
205
|
+
|
|
206
|
+
# Clean output for scripts (suppress all non-JSON noise)
|
|
207
|
+
jira-cli issue get PROJ-123 --json --quiet
|
|
208
|
+
|
|
209
|
+
# Preview destructive operations without executing
|
|
210
|
+
jira-cli issue delete PROJ-123 --dry-run --json
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Error responses include machine-readable error codes and actionable hints:
|
|
214
|
+
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"error": "Jira API error 404: Issue does not exist",
|
|
218
|
+
"statusCode": 404,
|
|
219
|
+
"errorCode": "NOT_FOUND",
|
|
220
|
+
"hint": "Verify the issue key exists and you have permission to view it"
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Set `NO_COLOR=1` to disable colored output (useful in CI/CD).
|
|
225
|
+
|
|
226
|
+
Run `jira-cli reference` to get a complete listing of all commands and flags in structured markdown.
|
|
227
|
+
|
|
228
|
+
## Environment Variables
|
|
229
|
+
|
|
230
|
+
| Variable | Description |
|
|
231
|
+
|---|---|
|
|
232
|
+
| `JIRA_HOST` | Jira Data Center host URL (overrides config file) |
|
|
233
|
+
| `JIRA_TOKEN` | Personal Access Token (overrides config file) |
|
|
234
|
+
| `NO_COLOR` | Set to any value to disable colored output ([no-color.org](https://no-color.org)) |
|
|
235
|
+
| `JIRA_CLI_USER_AGENT` | Custom User-Agent string for HTTP requests |
|
|
236
|
+
| `JIRA_NO_AUDIT` | Set to `1` to disable audit logging |
|
|
237
|
+
| `JIRA_AUDIT_RETENTION_MONTHS` | Auto-delete audit files older than N months (default: `3`, `0` = keep forever) |
|
|
238
|
+
|
|
239
|
+
## Config File
|
|
240
|
+
|
|
241
|
+
Credentials stored at `~/.jira-cli/config.json` (permissions: 0600):
|
|
242
|
+
|
|
243
|
+
```json
|
|
244
|
+
{
|
|
245
|
+
"host": "https://jira.company.com",
|
|
246
|
+
"token": "your-personal-access-token"
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Global Flags
|
|
251
|
+
|
|
252
|
+
| Flag | Description |
|
|
253
|
+
|---|---|
|
|
254
|
+
| `--json` | Output as JSON (flat format by default; use `--raw` for full Jira response) |
|
|
255
|
+
| `--force` | Skip interactive confirmation prompts |
|
|
256
|
+
| `--quiet` | Suppress non-JSON stdout output (for scripts and AI Agents) |
|
|
257
|
+
| `--dry-run` | Show what would be done without executing (write commands only) |
|
|
258
|
+
|
|
259
|
+
### Per-command flags
|
|
260
|
+
|
|
261
|
+
| Flag | Commands | Description |
|
|
262
|
+
|---|---|---|
|
|
263
|
+
| `--raw` | `issue get`, `issue list`, `search`, `sprint list`, `sprint issues`, `sprint active` | Return raw Jira API response instead of flat format |
|
|
264
|
+
| `--fields` | `issue get`, `issue list`, `sprint list`, `sprint issues` | Output only specified fields (e.g. `--fields key,summary,status`) |
|
|
265
|
+
|
|
266
|
+
## Troubleshooting
|
|
267
|
+
|
|
268
|
+
| Issue | Solution |
|
|
269
|
+
|---|---|
|
|
270
|
+
| Config not found | Run `jira-cli login` or set `JIRA_HOST` and `JIRA_TOKEN` env vars |
|
|
271
|
+
| Authentication failed | Regenerate PAT in your Jira DC profile settings |
|
|
272
|
+
| Permission denied | Check your PAT scope and project permissions |
|
|
273
|
+
| Resource not found | Verify the issue key or project key exists |
|
|
274
|
+
| Rate limited (429) | The CLI auto-retries; reduce request frequency if persistent |
|
|
275
|
+
| Host must start with https:// | Ensure your host URL includes the `https://` protocol |
|
|
276
|
+
|
|
277
|
+
## Security
|
|
278
|
+
|
|
279
|
+
- Credentials are stored locally at `~/.jira-cli/config.json` with `0600` file permissions (user-only readable)
|
|
280
|
+
- Config directory is created with `0700` permissions
|
|
281
|
+
- PAT input is hidden during `jira-cli login` (uses terminal secure input)
|
|
282
|
+
- All communication uses HTTPS (host must start with `https://`)
|
|
283
|
+
- No credentials are logged or transmitted to third parties
|
|
284
|
+
- Environment variables `JIRA_HOST` and `JIRA_TOKEN` take precedence over config file
|
|
285
|
+
|
|
286
|
+
> **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.
|
|
287
|
+
|
|
288
|
+
For vulnerability reports, see [SECURITY.md](SECURITY.md).
|
|
289
|
+
|
|
290
|
+
## Audit Logging
|
|
291
|
+
|
|
292
|
+
Every write command (create, edit, delete, transition, assign, comment, etc.) is automatically logged to `~/.jira-cli/audit/` in JSONL format — one JSON object per line, one file per month.
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
# Example: view today's audit log
|
|
296
|
+
cat ~/.jira-cli/audit/audit-2026-05.jsonl
|
|
297
|
+
|
|
298
|
+
# Each entry looks like:
|
|
299
|
+
# {"ts":"2026-05-03T14:22:01+08:00","cmd":"issue edit","args":["issue","edit","PROJ-123","--summary","new"],"exit":0,"ms":2031}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Configuration
|
|
303
|
+
|
|
304
|
+
| Env var | Default | Description |
|
|
305
|
+
|---------|---------|-------------|
|
|
306
|
+
| `JIRA_NO_AUDIT` | (unset) | Set to `1` to disable audit logging entirely |
|
|
307
|
+
| `JIRA_AUDIT_RETENTION_MONTHS` | `3` | Auto-delete audit files older than N months. Set to `0` to keep forever. |
|
|
308
|
+
|
|
309
|
+
Cleanup runs lazily on each write command — no background process or cron needed.
|
|
310
|
+
|
|
311
|
+
## E2E Integration Tests
|
|
312
|
+
|
|
313
|
+
A comprehensive E2E test script covers **every jira-cli command** (55+ operations) against a real Jira Data Center instance.
|
|
314
|
+
|
|
315
|
+
### Quick start
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
# Read-only mode (safe — no data is modified)
|
|
319
|
+
export JIRA_HOST=https://jira.company.com
|
|
320
|
+
export JIRA_TOKEN=<your-pat>
|
|
321
|
+
export JIRA_E2E_MUTATE=0
|
|
322
|
+
pwsh ./scripts/e2e-full.ps1
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Full test (creates and deletes test issues, filters)
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
pwsh ./scripts/e2e-full.ps1
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### With sprint write tests
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
export JIRA_E2E_SPRINT=1
|
|
335
|
+
pwsh ./scripts/e2e-full.ps1
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
The script produces:
|
|
339
|
+
- Terminal summary with PASS / FAIL / SKIP counts
|
|
340
|
+
- `scripts/e2e-report.csv` — machine-readable results for CI dashboards
|
|
341
|
+
|
|
342
|
+
### Environment variables
|
|
343
|
+
|
|
344
|
+
| Variable | Default | Description |
|
|
345
|
+
|---|---|---|
|
|
346
|
+
| `JIRA_HOST` | required | Jira DC host URL |
|
|
347
|
+
| `JIRA_TOKEN` | required | Personal Access Token |
|
|
348
|
+
| `JIRA_CLI_BIN` | `jira-cli` | Path to binary |
|
|
349
|
+
| `JIRA_E2E_PROJECT` | auto-detect | Force a project key |
|
|
350
|
+
| `JIRA_E2E_MUTATE` | `1` | Set `0` for read-only tests |
|
|
351
|
+
| `JIRA_E2E_SPRINT` | `0` | Set `1` for sprint write tests |
|
|
352
|
+
| `JIRA_E2E_CLEANUP` | `1` | Set `0` to keep test resources |
|
|
353
|
+
|
|
354
|
+
## Project Structure
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
jira-cli/
|
|
358
|
+
├── cmd/
|
|
359
|
+
│ ├── jira-cli/
|
|
360
|
+
│ │ └── main.go # Entry point (semantic exit codes)
|
|
361
|
+
│ ├── root.go # Root command, global flags, error handling
|
|
362
|
+
│ ├── login.go # Authentication (PAT-only, non-interactive)
|
|
363
|
+
│ ├── doctor.go # Diagnostics
|
|
364
|
+
│ ├── issue.go # Issue CRUD
|
|
365
|
+
│ ├── issue_*.go # Issue sub-commands
|
|
366
|
+
│ ├── flatten.go # Flat JSON output helpers (issues, sprints)
|
|
367
|
+
│ ├── reference.go # Self-documenting command reference
|
|
368
|
+
│ ├── sprint.go # Sprint management
|
|
369
|
+
│ ├── board.go # Board operations
|
|
370
|
+
│ ├── project.go # Project management
|
|
371
|
+
│ ├── search.go # JQL search
|
|
372
|
+
│ ├── user.go # User operations
|
|
373
|
+
│ ├── filter.go # Saved filters
|
|
374
|
+
│ └── epic.go # Epic operations
|
|
375
|
+
├── internal/
|
|
376
|
+
│ ├── api/ # Jira REST API v2 client + types
|
|
377
|
+
│ ├── audit/ # Write-operation audit logging (JSONL)
|
|
378
|
+
│ ├── config/ # Config file + env var management
|
|
379
|
+
│ └── output/ # Output formatting (tables, colors, flatten types)
|
|
380
|
+
├── scripts/
|
|
381
|
+
│ ├── install.js # npm postinstall (downloads binary)
|
|
382
|
+
│ ├── run.js # npm bin wrapper
|
|
383
|
+
│ └── e2e-full.ps1 # Full E2E integration tests (all commands)
|
|
384
|
+
├── skills/ # AI Agent Skill (bundled for install-skill)
|
|
385
|
+
├── package.json # npm distribution
|
|
386
|
+
├── .goreleaser.yml # Release automation
|
|
387
|
+
├── Makefile # Local development
|
|
388
|
+
└── .github/workflows/ # CI/CD
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## Contributing
|
|
392
|
+
|
|
393
|
+
Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md). Release notes: [CHANGELOG.md](CHANGELOG.md).
|
|
394
|
+
|
|
395
|
+
## License
|
|
396
|
+
|
|
397
|
+
MIT © fatecannotbealtered
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
Security fixes are applied to the latest minor release on the default branch (`main`). Release binaries are published via GitHub Releases and the npm package `@fatecannotbealtered-/jira-cli`.
|
|
6
|
+
|
|
7
|
+
## Reporting a vulnerability
|
|
8
|
+
|
|
9
|
+
Please **do not** file a public GitHub issue for undisclosed security vulnerabilities.
|
|
10
|
+
|
|
11
|
+
Instead, report privately via [GitHub Security Advisories](https://github.com/fatecannotbealtered/jira-cli/security/advisories/new) for this repository, or contact the maintainers through the contact options on the repository homepage.
|
|
12
|
+
|
|
13
|
+
Include:
|
|
14
|
+
|
|
15
|
+
- Description of the issue and impact
|
|
16
|
+
- Steps to reproduce (if safe to share)
|
|
17
|
+
- Affected versions or install methods (binary / npm / `go install`)
|
|
18
|
+
|
|
19
|
+
You should receive an acknowledgment as capacity allows. Thank you for helping keep users safe.
|
|
20
|
+
|
|
21
|
+
## Credential handling (design)
|
|
22
|
+
|
|
23
|
+
- Credentials are stored only in `~/.jira-cli/config.json` with file mode `0600` and directory `0700`.
|
|
24
|
+
- API tokens are read with hidden input in interactive terminals.
|
|
25
|
+
- Traffic is HTTPS-only to the configured Jira Data Center host (host must start with `https://`).
|
|
26
|
+
- Environment variables `JIRA_HOST` and `JIRA_TOKEN` take precedence over config file; prefer them in CI/Agent workflows to avoid persisting credentials on disk.
|
|
27
|
+
|
|
28
|
+
Review these assumptions when integrating jira-cli into automation or AI agent workflows.
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fatecannotbealtered-/jira-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
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
|
+
"keywords": [
|
|
6
|
+
"jira",
|
|
7
|
+
"cli",
|
|
8
|
+
"atlassian",
|
|
9
|
+
"ai-agent",
|
|
10
|
+
"devtools",
|
|
11
|
+
"sprint",
|
|
12
|
+
"issue-tracker",
|
|
13
|
+
"openclaw"
|
|
14
|
+
],
|
|
15
|
+
"author": "guosong6886@gmail.com",
|
|
16
|
+
"homepage": "https://github.com/fatecannotbealtered/jira-cli#readme",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/fatecannotbealtered/jira-cli/issues"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/fatecannotbealtered/jira-cli.git"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"bin": {
|
|
26
|
+
"jira-cli": "scripts/run.js"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"postinstall": "node scripts/install.js"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"scripts/install.js",
|
|
33
|
+
"scripts/run.js",
|
|
34
|
+
"skills/",
|
|
35
|
+
"CHANGELOG.md",
|
|
36
|
+
"CONTRIBUTING.md",
|
|
37
|
+
"SECURITY.md"
|
|
38
|
+
],
|
|
39
|
+
"os": [
|
|
40
|
+
"darwin",
|
|
41
|
+
"linux",
|
|
42
|
+
"win32"
|
|
43
|
+
],
|
|
44
|
+
"cpu": [
|
|
45
|
+
"x64",
|
|
46
|
+
"arm64"
|
|
47
|
+
],
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=16"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const crypto = require("crypto");
|
|
7
|
+
const { execFileSync } = require("child_process");
|
|
8
|
+
const os = require("os");
|
|
9
|
+
|
|
10
|
+
const VERSION = require("../package.json").version;
|
|
11
|
+
const REPO = "fatecannotbealtered/jira-cli";
|
|
12
|
+
const NAME = "jira-cli";
|
|
13
|
+
|
|
14
|
+
const PLATFORM_MAP = {
|
|
15
|
+
darwin: "darwin",
|
|
16
|
+
linux: "linux",
|
|
17
|
+
win32: "windows",
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const ARCH_MAP = {
|
|
21
|
+
x64: "amd64",
|
|
22
|
+
arm64: "arm64",
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const platform = PLATFORM_MAP[process.platform];
|
|
26
|
+
let arch = ARCH_MAP[process.arch];
|
|
27
|
+
|
|
28
|
+
// Windows ARM64: fall back to amd64 (runs via emulation)
|
|
29
|
+
if (process.platform === "win32" && process.arch === "arm64") {
|
|
30
|
+
console.log("Windows ARM64 detected, falling back to x64 binary (runs via emulation)");
|
|
31
|
+
arch = "amd64";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!platform || !arch) {
|
|
35
|
+
console.error(`Unsupported platform: ${process.platform}-${process.arch}`);
|
|
36
|
+
console.error(`\nManually download from:\n https://github.com/${REPO}/releases`);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const isWindows = process.platform === "win32";
|
|
41
|
+
const ext = isWindows ? ".zip" : ".tar.gz";
|
|
42
|
+
const archiveName = `${NAME}-${VERSION}-${platform}-${arch}${ext}`;
|
|
43
|
+
const GITHUB_URL = `https://github.com/${REPO}/releases/download/v${VERSION}/${archiveName}`;
|
|
44
|
+
|
|
45
|
+
const binDir = path.join(__dirname, "..", "bin");
|
|
46
|
+
const dest = path.join(binDir, NAME + (isWindows ? ".exe" : ""));
|
|
47
|
+
|
|
48
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
49
|
+
|
|
50
|
+
function download(url, destPath) {
|
|
51
|
+
const args = [
|
|
52
|
+
"--fail", "--location", "--silent", "--show-error",
|
|
53
|
+
"--connect-timeout", "15", "--max-time", "120",
|
|
54
|
+
"--output", destPath, url,
|
|
55
|
+
];
|
|
56
|
+
if (isWindows) {
|
|
57
|
+
args.unshift("--ssl-revoke-best-effort");
|
|
58
|
+
}
|
|
59
|
+
execFileSync("curl", args, { stdio: ["ignore", "ignore", "pipe"] });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function verifyChecksum(filePath, expectedHash) {
|
|
63
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
64
|
+
const hash = crypto.createHash("sha256").update(fileBuffer).digest("hex");
|
|
65
|
+
if (hash !== expectedHash) {
|
|
66
|
+
throw new Error(
|
|
67
|
+
`Checksum mismatch!\n Expected: ${expectedHash}\n Actual: ${hash}`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function install() {
|
|
73
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "jira-cli-"));
|
|
74
|
+
const archivePath = path.join(tmpDir, archiveName);
|
|
75
|
+
const checksumURL = `https://github.com/${REPO}/releases/download/v${VERSION}/checksums.txt`;
|
|
76
|
+
const checksumPath = path.join(tmpDir, "checksums.txt");
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
console.log(`Downloading ${NAME} v${VERSION} for ${platform}-${arch}...`);
|
|
80
|
+
download(GITHUB_URL, archivePath);
|
|
81
|
+
|
|
82
|
+
// Verify checksum
|
|
83
|
+
try {
|
|
84
|
+
download(checksumURL, checksumPath);
|
|
85
|
+
const checksumContent = fs.readFileSync(checksumPath, "utf8");
|
|
86
|
+
const line = checksumContent
|
|
87
|
+
.split("\n")
|
|
88
|
+
.find((l) => l.includes(archiveName));
|
|
89
|
+
if (line) {
|
|
90
|
+
const expectedHash = line.trim().split(/\s+/)[0];
|
|
91
|
+
verifyChecksum(archivePath, expectedHash);
|
|
92
|
+
console.log("✔ Checksum verified");
|
|
93
|
+
} else {
|
|
94
|
+
console.warn("Warning: archive not found in checksums.txt, skipping verification");
|
|
95
|
+
}
|
|
96
|
+
} catch (checksumErr) {
|
|
97
|
+
if (checksumErr.message.includes("Checksum mismatch")) {
|
|
98
|
+
throw checksumErr;
|
|
99
|
+
}
|
|
100
|
+
console.warn("Warning: could not verify checksum —", checksumErr.message);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Extract binary
|
|
104
|
+
if (isWindows) {
|
|
105
|
+
execFileSync("powershell", [
|
|
106
|
+
"-Command",
|
|
107
|
+
`Expand-Archive -Path '${archivePath}' -DestinationPath '${tmpDir}' -Force`,
|
|
108
|
+
], { stdio: "ignore" });
|
|
109
|
+
} else {
|
|
110
|
+
execFileSync("tar", ["-xzf", archivePath, "-C", tmpDir], {
|
|
111
|
+
stdio: "ignore",
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const binaryName = NAME + (isWindows ? ".exe" : "");
|
|
116
|
+
const extractedBinary = path.join(tmpDir, binaryName);
|
|
117
|
+
|
|
118
|
+
fs.copyFileSync(extractedBinary, dest);
|
|
119
|
+
if (!isWindows) {
|
|
120
|
+
fs.chmodSync(dest, 0o755);
|
|
121
|
+
}
|
|
122
|
+
console.log(`✔ ${NAME} v${VERSION} installed successfully`);
|
|
123
|
+
} finally {
|
|
124
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
install();
|
|
130
|
+
} catch (err) {
|
|
131
|
+
console.error(`Failed to install ${NAME}:`, err.message);
|
|
132
|
+
console.error(
|
|
133
|
+
`\nManually download from:\n https://github.com/${REPO}/releases\n`
|
|
134
|
+
);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
package/scripts/run.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const { execFileSync } = require("child_process");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
|
|
7
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
8
|
+
const bin = path.join(__dirname, "..", "bin", "jira-cli" + ext);
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
execFileSync(bin, process.argv.slice(2), { stdio: "inherit" });
|
|
12
|
+
} catch (e) {
|
|
13
|
+
if (e.code === "ENOENT") {
|
|
14
|
+
console.error("Binary not found. Run 'npm install -g @fatecannotbealtered-/jira-cli' to reinstall.");
|
|
15
|
+
}
|
|
16
|
+
process.exit(e.status || 1);
|
|
17
|
+
}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
---
|
|
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.
|
|
4
|
+
metadata: {"openclaw":{"emoji":"🎯","requires":{"bins":["jira-cli"]}}}
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# jira-cli
|
|
8
|
+
|
|
9
|
+
Jira Data Center CLI for humans and AI Agents. Supports **Jira DC only** (self-hosted), not Jira Cloud.
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
Before using any command, authenticate with a Jira DC instance. Follow these steps in order:
|
|
14
|
+
|
|
15
|
+
1. Ask the user for their Jira DC URL (e.g. `https://jira.company.com`). It must start with `https://`.
|
|
16
|
+
2. Ask the user for a **Personal Access Token (PAT)**. If they don't have one, guide them:
|
|
17
|
+
"Log in to your Jira DC → click your profile avatar → Personal Access Tokens → Create token."
|
|
18
|
+
3. Run `jira-cli login --host <URL> --token <PAT>` to save credentials.
|
|
19
|
+
4. Run `jira-cli doctor --json` to verify connectivity. If `authValid` is `true`, you're ready.
|
|
20
|
+
|
|
21
|
+
**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.
|
|
22
|
+
|
|
23
|
+
**Always use `--json` flag when parsing output.** Without it, output is human-formatted and not suitable for programmatic use.
|
|
24
|
+
|
|
25
|
+
## Safety
|
|
26
|
+
|
|
27
|
+
- **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.
|
|
28
|
+
- **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`.
|
|
29
|
+
- **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.
|
|
30
|
+
- All write operations are recorded in `~/.jira-cli/audit/` for traceability.
|
|
31
|
+
|
|
32
|
+
## Issue Management
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# View issues (flat JSON by default — token-efficient)
|
|
36
|
+
jira-cli issue get PROJ-123 --json
|
|
37
|
+
jira-cli issue get PROJ-123 --json --fields key,summary,status,assignee # Only specific fields
|
|
38
|
+
jira-cli issue get PROJ-123 --json --raw # Full Jira API response
|
|
39
|
+
jira-cli issue list --project PROJ --json
|
|
40
|
+
jira-cli issue list --project PROJ --status "In Progress" --assignee me --json
|
|
41
|
+
jira-cli issue list --project PROJ --type Bug --priority High --limit 20 --json
|
|
42
|
+
|
|
43
|
+
# Create and edit
|
|
44
|
+
jira-cli issue create --project PROJ --summary "Fix login bug" --type Bug --json
|
|
45
|
+
jira-cli issue create --project PROJ --summary "New feature" --type Story --assignee me --priority High --json
|
|
46
|
+
jira-cli issue create --project PROJ --summary "Sized story" --type Story --field "Story Points=5" --json
|
|
47
|
+
jira-cli issue edit PROJ-123 --summary "Updated summary" --priority Medium
|
|
48
|
+
jira-cli issue edit PROJ-123 --field "Story Points=8" --field "Team=Backend"
|
|
49
|
+
jira-cli issue delete PROJ-123 --force # Skip confirmation prompt
|
|
50
|
+
|
|
51
|
+
# Clone an issue
|
|
52
|
+
jira-cli issue clone PROJ-123 --json # Clone with default summary
|
|
53
|
+
jira-cli issue clone PROJ-123 --summary "New title" --json # Clone with custom summary
|
|
54
|
+
jira-cli issue clone PROJ-123 --with-links --json # Clone with issue links
|
|
55
|
+
|
|
56
|
+
# Status transitions
|
|
57
|
+
jira-cli issue transitions PROJ-123 --json # List available transitions
|
|
58
|
+
jira-cli issue transition PROJ-123 "In Progress" # Transition to status (name required)
|
|
59
|
+
jira-cli issue transition PROJ-123 "Done" --json
|
|
60
|
+
|
|
61
|
+
# Bulk transition
|
|
62
|
+
jira-cli issue bulk-transition "Done" --issues PROJ-1,PROJ-2,PROJ-3 --json
|
|
63
|
+
jira-cli issue bulk-transition "In Progress" --jql "project = PROJ AND sprint = 10 AND status = 'To Do'" --json
|
|
64
|
+
|
|
65
|
+
# Assignment and watching
|
|
66
|
+
jira-cli issue assign PROJ-123 me # Assign to current user
|
|
67
|
+
jira-cli issue assign PROJ-123 johndoe # Assign by username (DC uses name, not accountId)
|
|
68
|
+
jira-cli issue unassign PROJ-123
|
|
69
|
+
jira-cli issue watch PROJ-123
|
|
70
|
+
jira-cli issue unwatch PROJ-123
|
|
71
|
+
jira-cli issue watchers PROJ-123 --json
|
|
72
|
+
jira-cli issue vote PROJ-123
|
|
73
|
+
jira-cli issue unvote PROJ-123
|
|
74
|
+
|
|
75
|
+
# Comments
|
|
76
|
+
jira-cli issue comment add PROJ-123 --body "Fixed in PR #42" --json
|
|
77
|
+
jira-cli issue comment list PROJ-123 --json
|
|
78
|
+
jira-cli issue comment delete PROJ-123 --id <commentId>
|
|
79
|
+
|
|
80
|
+
# Worklogs
|
|
81
|
+
jira-cli issue worklog add PROJ-123 --time 2h --comment "Debugging session" --json
|
|
82
|
+
jira-cli issue worklog add PROJ-123 --time 1h30m --started "2024-01-15T10:00:00.000+0000"
|
|
83
|
+
jira-cli issue worklog list PROJ-123 --json
|
|
84
|
+
|
|
85
|
+
# Links
|
|
86
|
+
jira-cli issue link-types --json # List available link types
|
|
87
|
+
jira-cli issue link PROJ-123 --to PROJ-456 --type "blocks"
|
|
88
|
+
jira-cli issue unlink <linkId>
|
|
89
|
+
jira-cli issue remote-link PROJ-123 --url https://pr.url --title "PR #42"
|
|
90
|
+
jira-cli issue remote-links PROJ-123 --json
|
|
91
|
+
|
|
92
|
+
# Attachments
|
|
93
|
+
jira-cli issue attach PROJ-123 --file ./screenshot.png
|
|
94
|
+
jira-cli issue attachments PROJ-123 --json
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Search (JQL)
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Basic search
|
|
101
|
+
jira-cli search "assignee = currentUser() AND status != Done" --json
|
|
102
|
+
jira-cli search "project = PROJ AND sprint in openSprints()" --json
|
|
103
|
+
|
|
104
|
+
# Advanced options
|
|
105
|
+
jira-cli search "project = PROJ" --limit 100 --json
|
|
106
|
+
jira-cli search "project = PROJ" --all --json # Fetch ALL results (auto-paginate)
|
|
107
|
+
jira-cli search "project = PROJ" --count # Only show total count
|
|
108
|
+
jira-cli search "project = PROJ" --order-by updated --json
|
|
109
|
+
jira-cli search "type = Bug AND priority = High" --fields key,summary,status --json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Sprint Management
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
jira-cli board list --json # Find board IDs first
|
|
116
|
+
jira-cli sprint list --board 42 --json
|
|
117
|
+
jira-cli sprint list --board 42 --state active --json
|
|
118
|
+
jira-cli sprint active --board 42 --json # Active sprint + issues
|
|
119
|
+
jira-cli sprint issues --sprint 10 --json
|
|
120
|
+
jira-cli sprint create --board 42 --name "Sprint 5" --start-date 2024-02-01 --end-date 2024-02-14 --json
|
|
121
|
+
jira-cli sprint update --sprint 10 --goal "Complete payment refactor"
|
|
122
|
+
jira-cli sprint move --sprint 10 --issues PROJ-123,PROJ-124,PROJ-125
|
|
123
|
+
jira-cli sprint close --sprint 10 --force # --force skips confirmation
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Board & Backlog
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
jira-cli board list --json
|
|
130
|
+
jira-cli board list --project PROJ --type scrum --json
|
|
131
|
+
jira-cli board get --board 42 --json
|
|
132
|
+
jira-cli board backlog --board 42 --json
|
|
133
|
+
jira-cli board epics --board 42 --json
|
|
134
|
+
jira-cli board sprints --board 42 --state active --json
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Epic Management
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
jira-cli epic list --board 42 --json
|
|
141
|
+
jira-cli epic list --board 42 --done --json # Completed epics only
|
|
142
|
+
jira-cli epic issues PROJ-1 --board 42 --json
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Project Management
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
jira-cli project list --json
|
|
149
|
+
jira-cli project list --type software --json
|
|
150
|
+
jira-cli project get PROJ --json
|
|
151
|
+
jira-cli project components PROJ --json
|
|
152
|
+
jira-cli project versions PROJ --json
|
|
153
|
+
jira-cli project versions PROJ --unreleased --json
|
|
154
|
+
jira-cli project issue-types PROJ --json
|
|
155
|
+
jira-cli project fields --json # List all fields (system + custom)
|
|
156
|
+
jira-cli project fields --custom --json # List custom fields only
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## User Search
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
jira-cli user me --json # Current user info
|
|
163
|
+
jira-cli user search --query "john" --json
|
|
164
|
+
jira-cli user search --query "john" --assignable --project PROJ --json
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Filters
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
jira-cli filter list --json
|
|
171
|
+
jira-cli filter get <filterId> --json
|
|
172
|
+
jira-cli filter create --name "My Bugs" --jql "assignee = me AND type = Bug" --json
|
|
173
|
+
jira-cli filter run <filterId> --json
|
|
174
|
+
jira-cli filter delete <filterId>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Workflow Examples
|
|
178
|
+
|
|
179
|
+
### Find and update an issue
|
|
180
|
+
```bash
|
|
181
|
+
# 1. Search for issues
|
|
182
|
+
jira-cli search "project = PROJ AND assignee = me AND status = 'In Progress'" --json
|
|
183
|
+
|
|
184
|
+
# 2. Get issue details
|
|
185
|
+
jira-cli issue get PROJ-123 --json
|
|
186
|
+
|
|
187
|
+
# 3. Check available transitions
|
|
188
|
+
jira-cli issue transitions PROJ-123 --json
|
|
189
|
+
|
|
190
|
+
# 4. Transition to Done
|
|
191
|
+
jira-cli issue transition PROJ-123 "Done"
|
|
192
|
+
|
|
193
|
+
# 5. Add a comment
|
|
194
|
+
jira-cli issue comment add PROJ-123 --body "Completed and deployed to staging"
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Sprint planning workflow
|
|
198
|
+
```bash
|
|
199
|
+
# 1. Find the board
|
|
200
|
+
jira-cli board list --json
|
|
201
|
+
|
|
202
|
+
# 2. Check active sprint
|
|
203
|
+
jira-cli sprint active --board 42 --json
|
|
204
|
+
|
|
205
|
+
# 3. View backlog
|
|
206
|
+
jira-cli board backlog --board 42 --json
|
|
207
|
+
|
|
208
|
+
# 4. Create next sprint
|
|
209
|
+
jira-cli sprint create --board 42 --name "Sprint 6" --start-date 2024-02-15 --end-date 2024-02-28 --json
|
|
210
|
+
|
|
211
|
+
# 5. Move issues to sprint
|
|
212
|
+
jira-cli sprint move --sprint 11 --issues PROJ-200,PROJ-201,PROJ-202
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Guardrails
|
|
216
|
+
|
|
217
|
+
- Always run `jira-cli doctor --json` to verify auth before bulk operations
|
|
218
|
+
- `issue delete` requires typing the issue key to confirm. Use `--force` to skip confirmation in automated workflows
|
|
219
|
+
- `sprint close` is irreversible. Use `--force` to skip confirmation
|
|
220
|
+
- Use `--json` flag when parsing output in scripts or AI workflows
|
|
221
|
+
- Use `--dry-run` to preview what a write command would do without executing it
|
|
222
|
+
- Use `--quiet` with `--json` to suppress all non-JSON output (clean pipe-friendly output)
|
|
223
|
+
- `issue transition` requires the status name as the second argument (no interactive selection)
|
|
224
|
+
- When searching for usernames to use with `issue assign`, use `user search --query <name> --json` first
|
|
225
|
+
- DC uses **username** (not accountId) for user references. Use `jira-cli user me --json` to find your username
|
|
226
|
+
|
|
227
|
+
## Global Flags
|
|
228
|
+
|
|
229
|
+
- `--json` — Output as JSON (machine-readable, flat format by default)
|
|
230
|
+
- `--force` — Skip interactive confirmation prompts (for CI/Agent automation)
|
|
231
|
+
- `--quiet` — Suppress non-JSON stdout output (ideal for scripts and AI Agents)
|
|
232
|
+
- `--dry-run` — Show what would be done without executing (write commands only)
|
|
233
|
+
|
|
234
|
+
## Output Control Flags
|
|
235
|
+
|
|
236
|
+
These flags are available on read commands (`issue get`, `issue list`, `search`, `sprint list`, `sprint issues`):
|
|
237
|
+
|
|
238
|
+
- `--raw` — Return the full raw Jira API response instead of the token-efficient flat format
|
|
239
|
+
- `--fields key,summary,status` — Output only the specified fields (flat JSON mode only)
|
|
240
|
+
|
|
241
|
+
## JSON Output Schemas
|
|
242
|
+
|
|
243
|
+
### Flat Issue (default with --json)
|
|
244
|
+
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"key": "PROJ-123",
|
|
248
|
+
"summary": "Fix login bug",
|
|
249
|
+
"status": "In Progress",
|
|
250
|
+
"type": "Bug",
|
|
251
|
+
"assignee": "johndoe",
|
|
252
|
+
"reporter": "janedoe",
|
|
253
|
+
"priority": "High",
|
|
254
|
+
"created": "2024-01-15T10:30:00.000+0000",
|
|
255
|
+
"updated": "2024-01-16T14:20:00.000+0000",
|
|
256
|
+
"labels": "backend,urgent",
|
|
257
|
+
"component": "auth",
|
|
258
|
+
"parent": "PROJ-100"
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Flat Sprint
|
|
263
|
+
|
|
264
|
+
```json
|
|
265
|
+
{
|
|
266
|
+
"id": 42,
|
|
267
|
+
"name": "Sprint 5",
|
|
268
|
+
"state": "active",
|
|
269
|
+
"startDate": "2024-02-01",
|
|
270
|
+
"endDate": "2024-02-14",
|
|
271
|
+
"goal": "Complete payment module"
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Error Response (with --json)
|
|
276
|
+
|
|
277
|
+
```json
|
|
278
|
+
{
|
|
279
|
+
"error": "Jira API error 404: Issue does not exist",
|
|
280
|
+
"statusCode": 404,
|
|
281
|
+
"errorCode": "NOT_FOUND",
|
|
282
|
+
"hint": "Verify the issue key exists and you have permission to view it"
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Error Codes
|
|
287
|
+
|
|
288
|
+
| Code | Status | Hint |
|
|
289
|
+
|------|--------|------|
|
|
290
|
+
| `AUTH_REQUIRED` | 401 | Run `jira-cli login` or set JIRA_HOST and JIRA_TOKEN |
|
|
291
|
+
| `FORBIDDEN` | 403 | Check your PAT scope and project permissions |
|
|
292
|
+
| `NOT_FOUND` | 404 | Verify the resource key/ID exists |
|
|
293
|
+
| `RATE_LIMITED` | 429 | Wait and retry; reduce request frequency |
|
|
294
|
+
| `SERVER_ERROR` | 5xx | Jira server error; retry later |
|
|
295
|
+
| `NETWORK_ERROR` | — | Check host URL and network connectivity |
|
|
296
|
+
| `CONFIG_ERROR` | — | Run `jira-cli login` or set env vars |
|
|
297
|
+
|
|
298
|
+
### Exit Codes
|
|
299
|
+
|
|
300
|
+
| Code | Meaning |
|
|
301
|
+
|------|---------|
|
|
302
|
+
| 0 | Success |
|
|
303
|
+
| 2 | Bad arguments |
|
|
304
|
+
| 3 | Authentication error |
|
|
305
|
+
| 4 | Resource not found |
|
|
306
|
+
| 5 | Forbidden |
|
|
307
|
+
| 6 | Rate limited |
|
|
308
|
+
| 7 | Network/server error |
|
|
309
|
+
|
|
310
|
+
## Audit Logging
|
|
311
|
+
|
|
312
|
+
All write commands are automatically logged to `~/.jira-cli/audit/` in JSONL format (one file per month). Each entry records the command, arguments, exit code, and duration.
|
|
313
|
+
|
|
314
|
+
| Env var | Default | Description |
|
|
315
|
+
|---------|---------|-------------|
|
|
316
|
+
| `JIRA_NO_AUDIT` | (unset) | Set `1` to disable audit logging |
|
|
317
|
+
| `JIRA_AUDIT_RETENTION_MONTHS` | `3` | Auto-delete files older than N months (`0` = keep forever) |
|
|
318
|
+
|
|
319
|
+
## Self-Description
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
jira-cli reference # Print all commands, subcommands, and flags in structured markdown
|
|
323
|
+
```
|