jirasify 2.0.0__tar.gz

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.
@@ -0,0 +1,214 @@
1
+ Metadata-Version: 2.4
2
+ Name: jirasify
3
+ Version: 2.0.0
4
+ Summary: Terminal UI for Jira worklogs and status transitions
5
+ Author-email: Jakob Holst <code@jakobholst.dk>
6
+ License: MIT
7
+ Project-URL: Homepage, https://gitlab.com/jakobholst/jaho_local_bin
8
+ Project-URL: Repository, https://gitlab.com/jakobholst/jaho_local_bin
9
+ Keywords: jira,tui,worklog,textual,terminal
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: Software Development
17
+ Classifier: Topic :: Utilities
18
+ Requires-Python: >=3.14
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: requests>=2.28
21
+ Requires-Dist: textual>=0.50
22
+ Requires-Dist: pyyaml>=6.0
23
+
24
+ # jirasify
25
+
26
+ Terminal UI for logging work and moving Jira issues, built with [Textual](https://textual.textualize.io/).
27
+
28
+ The distribution name on PyPI is `jirasify`; the main CLI command is `jirasify-tui`; the importable Python module is `jiratui`.
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ pip install jirasify
34
+ ```
35
+
36
+ ## Configure
37
+
38
+ On first run, `jirasify-tui` writes a template config to `~/.local/etc/jiratui/config.yaml` and prints a usage page. Edit the file (or answer the interactive prompt to fill it) with your Jira URL, project key, and username.
39
+
40
+ Your Jira token is read from the environment variable named by `authentication.token_env` (default: `JIRATOKEN`):
41
+
42
+ ```bash
43
+ export JIRATOKEN=your_token
44
+ ```
45
+
46
+ - **Self-hosted Jira (Data Center / Server)**: use a **Personal Access Token**. It is sent as `Authorization: Bearer <token>`.
47
+ - **Atlassian Cloud** (URL contains `atlassian.net`): use an **API token** from your Atlassian account. It is combined with `assignee.username` (your account email) via HTTP Basic auth.
48
+
49
+ Verify connectivity before launching the TUI:
50
+
51
+ ```bash
52
+ jirasify-tui --test
53
+ ```
54
+
55
+ Prints the configured URL and token env var, then hits `/rest/api/2/myself`. Exits with a non-zero status on missing config, unset token, or auth failure.
56
+
57
+ ## Usage
58
+
59
+ ```bash
60
+ jirasify-tui
61
+ ```
62
+
63
+ | Key | Action |
64
+ | -------- | --------------------------------- |
65
+ | `l` | Log view |
66
+ | `o` | Overview |
67
+ | `r` | Monthly report |
68
+ | `t`/`w` | Today's / this week's report |
69
+ | `m` | This month's report |
70
+ | `s` | Change status of selected issue |
71
+ | `e` | Set estimate on selected issue |
72
+ | `h` | Help |
73
+ | `Ctrl+R` | Refresh |
74
+ | `q` | Quit |
75
+
76
+ Time input accepts `30m`, `1h`, `2h30m`, `1d` (a day = 8h).
77
+
78
+ ## `jirasify`
79
+
80
+ `pip install jirasify` also installs a `jirasify` command that turns a
81
+ structured Markdown file into Jira user stories using the same
82
+ `~/.local/etc/jiratui/config.yaml` and `JIRATOKEN` env var as `jirasify-tui`.
83
+
84
+ Expected Markdown layout:
85
+
86
+ ```markdown
87
+ # My Epic Name - User Stories
88
+
89
+ ## 1. Project Overview
90
+
91
+ Free text.
92
+
93
+ ---
94
+
95
+ # Phase 1 - Foundations
96
+
97
+ ## User Story 001 - Inventory Environment
98
+
99
+ **Estimate:** 15 h
100
+
101
+ > As a developer, I will document ... so that ...
102
+
103
+ ### Scope
104
+ - Item A
105
+ - Item B
106
+
107
+ ### Acceptance Criteria
108
+ - Criterion 1
109
+ - Criterion 2
110
+ ```
111
+
112
+ - The top-level `# ...` heading (any H1 that is not a `# Phase ...`) is used
113
+ as the Epic name. A trailing ` - User Stories` suffix is stripped.
114
+ - Stories are only picked up under a `## User Story ...` heading inside a
115
+ `# Phase ...` section.
116
+ - Recognised subsections: `Scope`, `Validate`, `Include`, `Examples`,
117
+ `Acceptance Criteria`.
118
+
119
+ ### Commands
120
+
121
+ ```bash
122
+ jirasify --example # write ./example.md (plain markdown starter)
123
+ jirasify --template --file stories.md.j2 # write an Ansible/Jinja2 template
124
+
125
+ jirasify --file stories.md # parse + write .jirastories.state.json
126
+ jirasify --file stories.md --create # ensure Epic exists, create missing stories linked to it (idempotent)
127
+ jirasify --file stories.md --status # key/status/assignee/epic/estimate/used per story, grouped by phase with totals
128
+ jirasify --file stories.md --epic VOS-100 # relink stories to a specific epic
129
+ jirasify --file stories.md --epic VOS-100 --story VOS-142 # relink a single story
130
+
131
+ jirasify --reverse VOS-1234 # print a markdown reconstruction of an Epic and its stories
132
+ jirasify --reverse VOS-1234 --save # write it to <Epic_Name>.md (spaces -> _)
133
+ ```
134
+
135
+ `--create` skips stories that already have an `issue_key` recorded in
136
+ `.jirastories.state.json`, and also skips summaries that already exist in the
137
+ target project, so re-runs won't duplicate issues. If no Epic with the H1's
138
+ name exists, one is created before the stories.
139
+
140
+ ### Ansible / Jinja2 template
141
+
142
+ `--template` emits a `.j2` scaffold expecting these variables:
143
+
144
+ - `epic_name` (string)
145
+ - `project_overview` (string, optional)
146
+ - `phases`: list of `{ name, stories: [ { id, summary, estimate, description, scope?, acceptance_criteria? } ] }`
147
+
148
+ Render it with `ansible.builtin.template` (or `jinja2.Template`) to produce
149
+ a `stories.md`, then run `jirasify --file stories.md --create`.
150
+
151
+ ## `jirasify-list`
152
+
153
+ `pip install jirasify` also installs a `jirasify-list` command for read-only
154
+ listing of Jira objects, using the same config as `jirasify-tui`.
155
+
156
+ ```bash
157
+ jirasify-list --epics # Epics in jira.project (config), excluding Cancelled and Done
158
+ jirasify-list --epics --key VOS # override the project key
159
+ ```
160
+
161
+ ### Status filters (mutually exclusive)
162
+
163
+ ```bash
164
+ jirasify-list --epics --active # status = Implementing
165
+ jirasify-list --epics --planning # status = Planning
166
+ jirasify-list --epics --done # status = Done
167
+ jirasify-list --epics --cancelled # status = Cancelled
168
+ ```
169
+
170
+ Without any of these flags, Cancelled and Done epics are hidden by default.
171
+
172
+ ### Parent Link filter
173
+
174
+ ```bash
175
+ jirasify-list --epics --parent VOS-100 # exact parent (JQL: "Parent Link" = VOS-100)
176
+ jirasify-list --epics --parent VOS # any parent whose key starts with VOS-
177
+ ```
178
+
179
+ ### Full hierarchy
180
+
181
+ ```bash
182
+ jirasify-list --epics --full # also show stories under each epic and subtasks under each story
183
+ ```
184
+
185
+ `--full` issues one extra batched JQL for all epic children (`"Epic Link" in (…)`)
186
+ and one for all subtasks (`parent in (…)`), regardless of item count.
187
+
188
+ ### Output
189
+
190
+ Epics are grouped by their Parent Link and printed as a tree with box-drawing
191
+ branches (`├──`, `└──`, `│`):
192
+
193
+ ```
194
+ VOS-100 Digital Platform Modernization
195
+ ├── VOS-215 Implementing Jane Doe Artifactory PyPI
196
+ │ ├── VOS-231 In Progress Bob Provision PyPI local repo
197
+ │ │ └── VOS-232 To Do Alice Configure retention
198
+ │ └── VOS-233 To Do Bob Assemble virtual PyPI
199
+ └── VOS-220 To Do Bob Sisyphos Onboarding
200
+
201
+ VOS-105 Infrastructure 2026
202
+ └── VOS-311 Implementing Alice VMware 9.1 Enablement
203
+
204
+ (no parent)
205
+ └── VOS-999 Planning Unassigned Ad-hoc Epic
206
+ ```
207
+
208
+ Columns per row: issue key, status, assignee (truncated to 32 chars with `…`),
209
+ and the label — Epic Name for epics (falls back to summary when the Epic Name
210
+ custom field is absent), summary for stories and subtasks. Without `--full`
211
+ only the epic level is shown.
212
+
213
+ Rows are colorized when stdout is a terminal: cyan parent header, magenta
214
+ epic, green story, blue subtask. Piping or redirecting produces plain output.
@@ -0,0 +1,191 @@
1
+ # jirasify
2
+
3
+ Terminal UI for logging work and moving Jira issues, built with [Textual](https://textual.textualize.io/).
4
+
5
+ The distribution name on PyPI is `jirasify`; the main CLI command is `jirasify-tui`; the importable Python module is `jiratui`.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install jirasify
11
+ ```
12
+
13
+ ## Configure
14
+
15
+ On first run, `jirasify-tui` writes a template config to `~/.local/etc/jiratui/config.yaml` and prints a usage page. Edit the file (or answer the interactive prompt to fill it) with your Jira URL, project key, and username.
16
+
17
+ Your Jira token is read from the environment variable named by `authentication.token_env` (default: `JIRATOKEN`):
18
+
19
+ ```bash
20
+ export JIRATOKEN=your_token
21
+ ```
22
+
23
+ - **Self-hosted Jira (Data Center / Server)**: use a **Personal Access Token**. It is sent as `Authorization: Bearer <token>`.
24
+ - **Atlassian Cloud** (URL contains `atlassian.net`): use an **API token** from your Atlassian account. It is combined with `assignee.username` (your account email) via HTTP Basic auth.
25
+
26
+ Verify connectivity before launching the TUI:
27
+
28
+ ```bash
29
+ jirasify-tui --test
30
+ ```
31
+
32
+ Prints the configured URL and token env var, then hits `/rest/api/2/myself`. Exits with a non-zero status on missing config, unset token, or auth failure.
33
+
34
+ ## Usage
35
+
36
+ ```bash
37
+ jirasify-tui
38
+ ```
39
+
40
+ | Key | Action |
41
+ | -------- | --------------------------------- |
42
+ | `l` | Log view |
43
+ | `o` | Overview |
44
+ | `r` | Monthly report |
45
+ | `t`/`w` | Today's / this week's report |
46
+ | `m` | This month's report |
47
+ | `s` | Change status of selected issue |
48
+ | `e` | Set estimate on selected issue |
49
+ | `h` | Help |
50
+ | `Ctrl+R` | Refresh |
51
+ | `q` | Quit |
52
+
53
+ Time input accepts `30m`, `1h`, `2h30m`, `1d` (a day = 8h).
54
+
55
+ ## `jirasify`
56
+
57
+ `pip install jirasify` also installs a `jirasify` command that turns a
58
+ structured Markdown file into Jira user stories using the same
59
+ `~/.local/etc/jiratui/config.yaml` and `JIRATOKEN` env var as `jirasify-tui`.
60
+
61
+ Expected Markdown layout:
62
+
63
+ ```markdown
64
+ # My Epic Name - User Stories
65
+
66
+ ## 1. Project Overview
67
+
68
+ Free text.
69
+
70
+ ---
71
+
72
+ # Phase 1 - Foundations
73
+
74
+ ## User Story 001 - Inventory Environment
75
+
76
+ **Estimate:** 15 h
77
+
78
+ > As a developer, I will document ... so that ...
79
+
80
+ ### Scope
81
+ - Item A
82
+ - Item B
83
+
84
+ ### Acceptance Criteria
85
+ - Criterion 1
86
+ - Criterion 2
87
+ ```
88
+
89
+ - The top-level `# ...` heading (any H1 that is not a `# Phase ...`) is used
90
+ as the Epic name. A trailing ` - User Stories` suffix is stripped.
91
+ - Stories are only picked up under a `## User Story ...` heading inside a
92
+ `# Phase ...` section.
93
+ - Recognised subsections: `Scope`, `Validate`, `Include`, `Examples`,
94
+ `Acceptance Criteria`.
95
+
96
+ ### Commands
97
+
98
+ ```bash
99
+ jirasify --example # write ./example.md (plain markdown starter)
100
+ jirasify --template --file stories.md.j2 # write an Ansible/Jinja2 template
101
+
102
+ jirasify --file stories.md # parse + write .jirastories.state.json
103
+ jirasify --file stories.md --create # ensure Epic exists, create missing stories linked to it (idempotent)
104
+ jirasify --file stories.md --status # key/status/assignee/epic/estimate/used per story, grouped by phase with totals
105
+ jirasify --file stories.md --epic VOS-100 # relink stories to a specific epic
106
+ jirasify --file stories.md --epic VOS-100 --story VOS-142 # relink a single story
107
+
108
+ jirasify --reverse VOS-1234 # print a markdown reconstruction of an Epic and its stories
109
+ jirasify --reverse VOS-1234 --save # write it to <Epic_Name>.md (spaces -> _)
110
+ ```
111
+
112
+ `--create` skips stories that already have an `issue_key` recorded in
113
+ `.jirastories.state.json`, and also skips summaries that already exist in the
114
+ target project, so re-runs won't duplicate issues. If no Epic with the H1's
115
+ name exists, one is created before the stories.
116
+
117
+ ### Ansible / Jinja2 template
118
+
119
+ `--template` emits a `.j2` scaffold expecting these variables:
120
+
121
+ - `epic_name` (string)
122
+ - `project_overview` (string, optional)
123
+ - `phases`: list of `{ name, stories: [ { id, summary, estimate, description, scope?, acceptance_criteria? } ] }`
124
+
125
+ Render it with `ansible.builtin.template` (or `jinja2.Template`) to produce
126
+ a `stories.md`, then run `jirasify --file stories.md --create`.
127
+
128
+ ## `jirasify-list`
129
+
130
+ `pip install jirasify` also installs a `jirasify-list` command for read-only
131
+ listing of Jira objects, using the same config as `jirasify-tui`.
132
+
133
+ ```bash
134
+ jirasify-list --epics # Epics in jira.project (config), excluding Cancelled and Done
135
+ jirasify-list --epics --key VOS # override the project key
136
+ ```
137
+
138
+ ### Status filters (mutually exclusive)
139
+
140
+ ```bash
141
+ jirasify-list --epics --active # status = Implementing
142
+ jirasify-list --epics --planning # status = Planning
143
+ jirasify-list --epics --done # status = Done
144
+ jirasify-list --epics --cancelled # status = Cancelled
145
+ ```
146
+
147
+ Without any of these flags, Cancelled and Done epics are hidden by default.
148
+
149
+ ### Parent Link filter
150
+
151
+ ```bash
152
+ jirasify-list --epics --parent VOS-100 # exact parent (JQL: "Parent Link" = VOS-100)
153
+ jirasify-list --epics --parent VOS # any parent whose key starts with VOS-
154
+ ```
155
+
156
+ ### Full hierarchy
157
+
158
+ ```bash
159
+ jirasify-list --epics --full # also show stories under each epic and subtasks under each story
160
+ ```
161
+
162
+ `--full` issues one extra batched JQL for all epic children (`"Epic Link" in (…)`)
163
+ and one for all subtasks (`parent in (…)`), regardless of item count.
164
+
165
+ ### Output
166
+
167
+ Epics are grouped by their Parent Link and printed as a tree with box-drawing
168
+ branches (`├──`, `└──`, `│`):
169
+
170
+ ```
171
+ VOS-100 Digital Platform Modernization
172
+ ├── VOS-215 Implementing Jane Doe Artifactory PyPI
173
+ │ ├── VOS-231 In Progress Bob Provision PyPI local repo
174
+ │ │ └── VOS-232 To Do Alice Configure retention
175
+ │ └── VOS-233 To Do Bob Assemble virtual PyPI
176
+ └── VOS-220 To Do Bob Sisyphos Onboarding
177
+
178
+ VOS-105 Infrastructure 2026
179
+ └── VOS-311 Implementing Alice VMware 9.1 Enablement
180
+
181
+ (no parent)
182
+ └── VOS-999 Planning Unassigned Ad-hoc Epic
183
+ ```
184
+
185
+ Columns per row: issue key, status, assignee (truncated to 32 chars with `…`),
186
+ and the label — Epic Name for epics (falls back to summary when the Epic Name
187
+ custom field is absent), summary for stories and subtasks. Without `--full`
188
+ only the epic level is shown.
189
+
190
+ Rows are colorized when stdout is a terminal: cyan parent header, magenta
191
+ epic, green story, blue subtask. Piping or redirecting produces plain output.
@@ -0,0 +1,42 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "jirasify"
7
+ version = "2.0.0"
8
+ description = "Terminal UI for Jira worklogs and status transitions"
9
+ readme = "README.md"
10
+ requires-python = ">=3.14"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "Jakob Holst", email = "code@jakobholst.dk" },
14
+ ]
15
+ keywords = ["jira", "tui", "worklog", "textual", "terminal"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Environment :: Console",
19
+ "Intended Audience :: Developers",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Operating System :: OS Independent",
22
+ "Programming Language :: Python :: 3",
23
+ "Topic :: Software Development",
24
+ "Topic :: Utilities",
25
+ ]
26
+ dependencies = [
27
+ "requests>=2.28",
28
+ "textual>=0.50",
29
+ "pyyaml>=6.0",
30
+ ]
31
+
32
+ [project.scripts]
33
+ jirasify-tui = "jiratui.app:main"
34
+ jirasify = "jiratui.markdown2jira:main"
35
+ jirasify-list = "jiratui.jira_list:main"
36
+
37
+ [project.urls]
38
+ Homepage = "https://gitlab.com/jakobholst/jaho_local_bin"
39
+ Repository = "https://gitlab.com/jakobholst/jaho_local_bin"
40
+
41
+ [tool.setuptools.packages.find]
42
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,214 @@
1
+ Metadata-Version: 2.4
2
+ Name: jirasify
3
+ Version: 2.0.0
4
+ Summary: Terminal UI for Jira worklogs and status transitions
5
+ Author-email: Jakob Holst <code@jakobholst.dk>
6
+ License: MIT
7
+ Project-URL: Homepage, https://gitlab.com/jakobholst/jaho_local_bin
8
+ Project-URL: Repository, https://gitlab.com/jakobholst/jaho_local_bin
9
+ Keywords: jira,tui,worklog,textual,terminal
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: Software Development
17
+ Classifier: Topic :: Utilities
18
+ Requires-Python: >=3.14
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: requests>=2.28
21
+ Requires-Dist: textual>=0.50
22
+ Requires-Dist: pyyaml>=6.0
23
+
24
+ # jirasify
25
+
26
+ Terminal UI for logging work and moving Jira issues, built with [Textual](https://textual.textualize.io/).
27
+
28
+ The distribution name on PyPI is `jirasify`; the main CLI command is `jirasify-tui`; the importable Python module is `jiratui`.
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ pip install jirasify
34
+ ```
35
+
36
+ ## Configure
37
+
38
+ On first run, `jirasify-tui` writes a template config to `~/.local/etc/jiratui/config.yaml` and prints a usage page. Edit the file (or answer the interactive prompt to fill it) with your Jira URL, project key, and username.
39
+
40
+ Your Jira token is read from the environment variable named by `authentication.token_env` (default: `JIRATOKEN`):
41
+
42
+ ```bash
43
+ export JIRATOKEN=your_token
44
+ ```
45
+
46
+ - **Self-hosted Jira (Data Center / Server)**: use a **Personal Access Token**. It is sent as `Authorization: Bearer <token>`.
47
+ - **Atlassian Cloud** (URL contains `atlassian.net`): use an **API token** from your Atlassian account. It is combined with `assignee.username` (your account email) via HTTP Basic auth.
48
+
49
+ Verify connectivity before launching the TUI:
50
+
51
+ ```bash
52
+ jirasify-tui --test
53
+ ```
54
+
55
+ Prints the configured URL and token env var, then hits `/rest/api/2/myself`. Exits with a non-zero status on missing config, unset token, or auth failure.
56
+
57
+ ## Usage
58
+
59
+ ```bash
60
+ jirasify-tui
61
+ ```
62
+
63
+ | Key | Action |
64
+ | -------- | --------------------------------- |
65
+ | `l` | Log view |
66
+ | `o` | Overview |
67
+ | `r` | Monthly report |
68
+ | `t`/`w` | Today's / this week's report |
69
+ | `m` | This month's report |
70
+ | `s` | Change status of selected issue |
71
+ | `e` | Set estimate on selected issue |
72
+ | `h` | Help |
73
+ | `Ctrl+R` | Refresh |
74
+ | `q` | Quit |
75
+
76
+ Time input accepts `30m`, `1h`, `2h30m`, `1d` (a day = 8h).
77
+
78
+ ## `jirasify`
79
+
80
+ `pip install jirasify` also installs a `jirasify` command that turns a
81
+ structured Markdown file into Jira user stories using the same
82
+ `~/.local/etc/jiratui/config.yaml` and `JIRATOKEN` env var as `jirasify-tui`.
83
+
84
+ Expected Markdown layout:
85
+
86
+ ```markdown
87
+ # My Epic Name - User Stories
88
+
89
+ ## 1. Project Overview
90
+
91
+ Free text.
92
+
93
+ ---
94
+
95
+ # Phase 1 - Foundations
96
+
97
+ ## User Story 001 - Inventory Environment
98
+
99
+ **Estimate:** 15 h
100
+
101
+ > As a developer, I will document ... so that ...
102
+
103
+ ### Scope
104
+ - Item A
105
+ - Item B
106
+
107
+ ### Acceptance Criteria
108
+ - Criterion 1
109
+ - Criterion 2
110
+ ```
111
+
112
+ - The top-level `# ...` heading (any H1 that is not a `# Phase ...`) is used
113
+ as the Epic name. A trailing ` - User Stories` suffix is stripped.
114
+ - Stories are only picked up under a `## User Story ...` heading inside a
115
+ `# Phase ...` section.
116
+ - Recognised subsections: `Scope`, `Validate`, `Include`, `Examples`,
117
+ `Acceptance Criteria`.
118
+
119
+ ### Commands
120
+
121
+ ```bash
122
+ jirasify --example # write ./example.md (plain markdown starter)
123
+ jirasify --template --file stories.md.j2 # write an Ansible/Jinja2 template
124
+
125
+ jirasify --file stories.md # parse + write .jirastories.state.json
126
+ jirasify --file stories.md --create # ensure Epic exists, create missing stories linked to it (idempotent)
127
+ jirasify --file stories.md --status # key/status/assignee/epic/estimate/used per story, grouped by phase with totals
128
+ jirasify --file stories.md --epic VOS-100 # relink stories to a specific epic
129
+ jirasify --file stories.md --epic VOS-100 --story VOS-142 # relink a single story
130
+
131
+ jirasify --reverse VOS-1234 # print a markdown reconstruction of an Epic and its stories
132
+ jirasify --reverse VOS-1234 --save # write it to <Epic_Name>.md (spaces -> _)
133
+ ```
134
+
135
+ `--create` skips stories that already have an `issue_key` recorded in
136
+ `.jirastories.state.json`, and also skips summaries that already exist in the
137
+ target project, so re-runs won't duplicate issues. If no Epic with the H1's
138
+ name exists, one is created before the stories.
139
+
140
+ ### Ansible / Jinja2 template
141
+
142
+ `--template` emits a `.j2` scaffold expecting these variables:
143
+
144
+ - `epic_name` (string)
145
+ - `project_overview` (string, optional)
146
+ - `phases`: list of `{ name, stories: [ { id, summary, estimate, description, scope?, acceptance_criteria? } ] }`
147
+
148
+ Render it with `ansible.builtin.template` (or `jinja2.Template`) to produce
149
+ a `stories.md`, then run `jirasify --file stories.md --create`.
150
+
151
+ ## `jirasify-list`
152
+
153
+ `pip install jirasify` also installs a `jirasify-list` command for read-only
154
+ listing of Jira objects, using the same config as `jirasify-tui`.
155
+
156
+ ```bash
157
+ jirasify-list --epics # Epics in jira.project (config), excluding Cancelled and Done
158
+ jirasify-list --epics --key VOS # override the project key
159
+ ```
160
+
161
+ ### Status filters (mutually exclusive)
162
+
163
+ ```bash
164
+ jirasify-list --epics --active # status = Implementing
165
+ jirasify-list --epics --planning # status = Planning
166
+ jirasify-list --epics --done # status = Done
167
+ jirasify-list --epics --cancelled # status = Cancelled
168
+ ```
169
+
170
+ Without any of these flags, Cancelled and Done epics are hidden by default.
171
+
172
+ ### Parent Link filter
173
+
174
+ ```bash
175
+ jirasify-list --epics --parent VOS-100 # exact parent (JQL: "Parent Link" = VOS-100)
176
+ jirasify-list --epics --parent VOS # any parent whose key starts with VOS-
177
+ ```
178
+
179
+ ### Full hierarchy
180
+
181
+ ```bash
182
+ jirasify-list --epics --full # also show stories under each epic and subtasks under each story
183
+ ```
184
+
185
+ `--full` issues one extra batched JQL for all epic children (`"Epic Link" in (…)`)
186
+ and one for all subtasks (`parent in (…)`), regardless of item count.
187
+
188
+ ### Output
189
+
190
+ Epics are grouped by their Parent Link and printed as a tree with box-drawing
191
+ branches (`├──`, `└──`, `│`):
192
+
193
+ ```
194
+ VOS-100 Digital Platform Modernization
195
+ ├── VOS-215 Implementing Jane Doe Artifactory PyPI
196
+ │ ├── VOS-231 In Progress Bob Provision PyPI local repo
197
+ │ │ └── VOS-232 To Do Alice Configure retention
198
+ │ └── VOS-233 To Do Bob Assemble virtual PyPI
199
+ └── VOS-220 To Do Bob Sisyphos Onboarding
200
+
201
+ VOS-105 Infrastructure 2026
202
+ └── VOS-311 Implementing Alice VMware 9.1 Enablement
203
+
204
+ (no parent)
205
+ └── VOS-999 Planning Unassigned Ad-hoc Epic
206
+ ```
207
+
208
+ Columns per row: issue key, status, assignee (truncated to 32 chars with `…`),
209
+ and the label — Epic Name for epics (falls back to summary when the Epic Name
210
+ custom field is absent), summary for stories and subtasks. Without `--full`
211
+ only the epic level is shown.
212
+
213
+ Rows are colorized when stdout is a terminal: cyan parent header, magenta
214
+ epic, green story, blue subtask. Piping or redirecting produces plain output.
@@ -0,0 +1,18 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/jirasify.egg-info/PKG-INFO
4
+ src/jirasify.egg-info/SOURCES.txt
5
+ src/jirasify.egg-info/dependency_links.txt
6
+ src/jirasify.egg-info/entry_points.txt
7
+ src/jirasify.egg-info/requires.txt
8
+ src/jirasify.egg-info/top_level.txt
9
+ src/jiratui/__init__.py
10
+ src/jiratui/__main__.py
11
+ src/jiratui/app.py
12
+ src/jiratui/client.py
13
+ src/jiratui/config.py
14
+ src/jiratui/dailywork.py
15
+ src/jiratui/jira_list.py
16
+ src/jiratui/markdown2jira.py
17
+ src/jiratui/screens.py
18
+ src/jiratui/utils.py
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ jirasify = jiratui.markdown2jira:main
3
+ jirasify-list = jiratui.jira_list:main
4
+ jirasify-tui = jiratui.app:main