azwork 0.1.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.
- azwork-0.1.0/PKG-INFO +259 -0
- azwork-0.1.0/README.md +232 -0
- azwork-0.1.0/azwork/__init__.py +3 -0
- azwork-0.1.0/azwork/__main__.py +84 -0
- azwork-0.1.0/azwork/api/__init__.py +0 -0
- azwork-0.1.0/azwork/api/client.py +215 -0
- azwork-0.1.0/azwork/api/models.py +182 -0
- azwork-0.1.0/azwork/api/wiql.py +61 -0
- azwork-0.1.0/azwork/config.py +75 -0
- azwork-0.1.0/azwork/export/__init__.py +0 -0
- azwork-0.1.0/azwork/export/markdown.py +122 -0
- azwork-0.1.0/azwork/export/prompt.py +37 -0
- azwork-0.1.0/azwork/tui/__init__.py +0 -0
- azwork-0.1.0/azwork/tui/app.py +33 -0
- azwork-0.1.0/azwork/tui/screens/__init__.py +0 -0
- azwork-0.1.0/azwork/tui/screens/detail_screen.py +239 -0
- azwork-0.1.0/azwork/tui/screens/list_screen.py +175 -0
- azwork-0.1.0/azwork/tui/widgets/__init__.py +0 -0
- azwork-0.1.0/azwork/tui/widgets/filter_bar.py +213 -0
- azwork-0.1.0/azwork/tui/widgets/item_table.py +109 -0
- azwork-0.1.0/azwork/utils.py +210 -0
- azwork-0.1.0/azwork.egg-info/PKG-INFO +259 -0
- azwork-0.1.0/azwork.egg-info/SOURCES.txt +31 -0
- azwork-0.1.0/azwork.egg-info/dependency_links.txt +1 -0
- azwork-0.1.0/azwork.egg-info/entry_points.txt +2 -0
- azwork-0.1.0/azwork.egg-info/requires.txt +9 -0
- azwork-0.1.0/azwork.egg-info/top_level.txt +1 -0
- azwork-0.1.0/pyproject.toml +45 -0
- azwork-0.1.0/setup.cfg +4 -0
- azwork-0.1.0/tests/test_api_client.py +171 -0
- azwork-0.1.0/tests/test_export_markdown.py +163 -0
- azwork-0.1.0/tests/test_html_conversion.py +176 -0
- azwork-0.1.0/tests/test_wiql.py +63 -0
azwork-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: azwork
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: TUI tool for triaging Azure DevOps work items
|
|
5
|
+
Author: Antonio Pastorino
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/a-pastorino/azwork
|
|
8
|
+
Project-URL: Repository, https://github.com/a-pastorino/azwork
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Topic :: Software Development :: Bug Tracking
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: textual>=0.47.0
|
|
20
|
+
Requires-Dist: requests>=2.31.0
|
|
21
|
+
Requires-Dist: beautifulsoup4>=4.12.0
|
|
22
|
+
Requires-Dist: pyperclip>=1.8.0
|
|
23
|
+
Requires-Dist: pyyaml>=6.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
26
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
|
|
27
|
+
|
|
28
|
+
# azwork
|
|
29
|
+
|
|
30
|
+
A terminal UI for triaging Azure DevOps work items. Browse, inspect, and export work items as Markdown — optimized for use as context in Claude Code sessions.
|
|
31
|
+
|
|
32
|
+

|
|
33
|
+

|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- **Interactive TUI** — browse work items in a filterable, sortable table
|
|
38
|
+
- **Detail view** — inspect description, repro steps, comments, relations, and custom fields
|
|
39
|
+
- **Markdown export** — export any work item to a clean `.md` file
|
|
40
|
+
- **Claude Code prompt export** — generate a ready-to-use prompt wrapping the work item
|
|
41
|
+
- **Clipboard support** — copy Markdown to clipboard with a single keystroke
|
|
42
|
+
- **Smart caching** — fetched work items are cached in memory to keep navigation fast
|
|
43
|
+
- **HTML → Markdown** — Azure DevOps HTML content is automatically converted
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install azwork
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Or install from source:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
git clone https://github.com/a-pastorino/azwork.git
|
|
55
|
+
cd azwork
|
|
56
|
+
pip install .
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
For development:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install -e ".[dev]"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Quick start
|
|
66
|
+
|
|
67
|
+
### 1. Create a Personal Access Token
|
|
68
|
+
|
|
69
|
+
Go to `https://dev.azure.com/{your-org}/_usersSettings/tokens` and create a token with the **Work Items → Read** scope.
|
|
70
|
+
|
|
71
|
+
Export it as an environment variable:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
export AZURE_DEVOPS_PAT="your-token-here"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 2. Run the setup wizard
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
azwork --setup
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
This creates `~/.azwork.yml` interactively.
|
|
84
|
+
|
|
85
|
+
### 3. Launch
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
azwork
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Usage
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Use defaults from ~/.azwork.yml
|
|
95
|
+
azwork
|
|
96
|
+
|
|
97
|
+
# Override org and project
|
|
98
|
+
azwork --org myorg --project myproject
|
|
99
|
+
|
|
100
|
+
# Custom export directory
|
|
101
|
+
azwork --output-dir ./sprint-bugs
|
|
102
|
+
|
|
103
|
+
# Re-run setup
|
|
104
|
+
azwork --setup
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Configuration
|
|
108
|
+
|
|
109
|
+
azwork reads its configuration from `~/.azwork.yml`. CLI arguments always take priority.
|
|
110
|
+
|
|
111
|
+
### `~/.azwork.yml` anatomy
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
# Azure DevOps organization name (the {org} part of dev.azure.com/{org})
|
|
115
|
+
org: myorg
|
|
116
|
+
|
|
117
|
+
# Project name within the organization
|
|
118
|
+
project: myproject
|
|
119
|
+
|
|
120
|
+
# Default directory where exported Markdown files are saved.
|
|
121
|
+
# Can be an absolute path or relative to where you run azwork.
|
|
122
|
+
# Created automatically on first export if it doesn't exist.
|
|
123
|
+
default_output_dir: ./bugs
|
|
124
|
+
|
|
125
|
+
# Work item types to include in queries.
|
|
126
|
+
# These are used both as WIQL filter and as options in the Type dropdown.
|
|
127
|
+
# Common values: Bug, Task, User Story, Epic, Feature, Issue, Test Case
|
|
128
|
+
work_item_types:
|
|
129
|
+
- Bug
|
|
130
|
+
- Task
|
|
131
|
+
- User Story
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
All fields are optional when using CLI overrides. The PAT is **never** stored in the config file — it is always read from the `AZURE_DEVOPS_PAT` environment variable.
|
|
135
|
+
|
|
136
|
+
### Minimal example
|
|
137
|
+
|
|
138
|
+
```yaml
|
|
139
|
+
org: contoso
|
|
140
|
+
project: webapp
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Full example
|
|
144
|
+
|
|
145
|
+
```yaml
|
|
146
|
+
org: contoso
|
|
147
|
+
project: webapp
|
|
148
|
+
default_output_dir: ~/work/bugs
|
|
149
|
+
work_item_types:
|
|
150
|
+
- Bug
|
|
151
|
+
- Task
|
|
152
|
+
- User Story
|
|
153
|
+
- Feature
|
|
154
|
+
- Epic
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Keybindings
|
|
158
|
+
|
|
159
|
+
### List screen
|
|
160
|
+
|
|
161
|
+
| Key | Action |
|
|
162
|
+
|-----|--------|
|
|
163
|
+
| `↑` `↓` | Navigate rows |
|
|
164
|
+
| `Enter` | Open detail view |
|
|
165
|
+
| `E` | Export highlighted item to Markdown |
|
|
166
|
+
| `R` | Refresh (re-fetch from API) |
|
|
167
|
+
| `Q` | Quit |
|
|
168
|
+
| `?` | Show help |
|
|
169
|
+
|
|
170
|
+
Column headers are clickable to sort by that column.
|
|
171
|
+
|
|
172
|
+
### Detail screen
|
|
173
|
+
|
|
174
|
+
| Key | Action |
|
|
175
|
+
|-----|--------|
|
|
176
|
+
| `Esc` | Back to list |
|
|
177
|
+
| `E` | Export as Markdown |
|
|
178
|
+
| `P` | Export as Claude Code prompt |
|
|
179
|
+
| `C` | Copy Markdown to clipboard |
|
|
180
|
+
| `O` | Open in browser |
|
|
181
|
+
| `?` | Show help |
|
|
182
|
+
|
|
183
|
+
## Export formats
|
|
184
|
+
|
|
185
|
+
### Markdown
|
|
186
|
+
|
|
187
|
+
A structured Markdown file with metadata table, description, repro steps, acceptance criteria, discussion thread, related items, and custom fields.
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
bugs/1234-login-fails-special-chars.md
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Claude Code prompt
|
|
194
|
+
|
|
195
|
+
Same Markdown content wrapped in a prompt template that instructs Claude Code to analyze and resolve the work item:
|
|
196
|
+
|
|
197
|
+
```markdown
|
|
198
|
+
# Task: Resolve the following work item
|
|
199
|
+
|
|
200
|
+
Analyze the work item described below and take the necessary actions to resolve it.
|
|
201
|
+
The project context is described in the CLAUDE.md file at the repository root.
|
|
202
|
+
|
|
203
|
+
## Work Item
|
|
204
|
+
[... full work item markdown ...]
|
|
205
|
+
|
|
206
|
+
## Instructions
|
|
207
|
+
1. Analyze the work item and identify the affected files
|
|
208
|
+
2. Implement the fix or the requested feature
|
|
209
|
+
3. Write or update tests to cover the case
|
|
210
|
+
4. Verify that existing tests are not broken
|
|
211
|
+
5. Briefly describe the changes you made
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Project structure
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
azwork/
|
|
218
|
+
├── __main__.py # CLI entry point (argparse)
|
|
219
|
+
├── config.py # YAML config loading + CLI merge
|
|
220
|
+
├── utils.py # HTML→Markdown conversion
|
|
221
|
+
├── api/
|
|
222
|
+
│ ├── client.py # Azure DevOps REST client (auth, batching, cache)
|
|
223
|
+
│ ├── wiql.py # WIQL query builder
|
|
224
|
+
│ └── models.py # WorkItem, Comment, Relation dataclasses
|
|
225
|
+
├── tui/
|
|
226
|
+
│ ├── app.py # Textual App
|
|
227
|
+
│ ├── screens/
|
|
228
|
+
│ │ ├── list_screen.py # Work item list with filters
|
|
229
|
+
│ │ └── detail_screen.py # Single item detail + export dialog
|
|
230
|
+
│ └── widgets/
|
|
231
|
+
│ ├── filter_bar.py # Type / State / Iteration / Search filters
|
|
232
|
+
│ └── item_table.py # Sortable DataTable for work items
|
|
233
|
+
└── export/
|
|
234
|
+
├── markdown.py # Markdown generation
|
|
235
|
+
└── prompt.py # Claude Code prompt wrapper
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Running tests
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
pytest
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Tests mock all API calls and cover:
|
|
245
|
+
|
|
246
|
+
- API client (pagination, HTTP errors, caching, response parsing)
|
|
247
|
+
- WIQL query construction with various filter combinations
|
|
248
|
+
- Markdown export (formatting, edge cases, empty fields)
|
|
249
|
+
- HTML → Markdown conversion (all supported tags)
|
|
250
|
+
|
|
251
|
+
## Requirements
|
|
252
|
+
|
|
253
|
+
- Python 3.10+
|
|
254
|
+
- An Azure DevOps organization with work items
|
|
255
|
+
- A PAT with **Work Items → Read** scope
|
|
256
|
+
|
|
257
|
+
## License
|
|
258
|
+
|
|
259
|
+
MIT
|
azwork-0.1.0/README.md
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# azwork
|
|
2
|
+
|
|
3
|
+
A terminal UI for triaging Azure DevOps work items. Browse, inspect, and export work items as Markdown — optimized for use as context in Claude Code sessions.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Interactive TUI** — browse work items in a filterable, sortable table
|
|
11
|
+
- **Detail view** — inspect description, repro steps, comments, relations, and custom fields
|
|
12
|
+
- **Markdown export** — export any work item to a clean `.md` file
|
|
13
|
+
- **Claude Code prompt export** — generate a ready-to-use prompt wrapping the work item
|
|
14
|
+
- **Clipboard support** — copy Markdown to clipboard with a single keystroke
|
|
15
|
+
- **Smart caching** — fetched work items are cached in memory to keep navigation fast
|
|
16
|
+
- **HTML → Markdown** — Azure DevOps HTML content is automatically converted
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install azwork
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or install from source:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git clone https://github.com/a-pastorino/azwork.git
|
|
28
|
+
cd azwork
|
|
29
|
+
pip install .
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
For development:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install -e ".[dev]"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Quick start
|
|
39
|
+
|
|
40
|
+
### 1. Create a Personal Access Token
|
|
41
|
+
|
|
42
|
+
Go to `https://dev.azure.com/{your-org}/_usersSettings/tokens` and create a token with the **Work Items → Read** scope.
|
|
43
|
+
|
|
44
|
+
Export it as an environment variable:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
export AZURE_DEVOPS_PAT="your-token-here"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 2. Run the setup wizard
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
azwork --setup
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This creates `~/.azwork.yml` interactively.
|
|
57
|
+
|
|
58
|
+
### 3. Launch
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
azwork
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Usage
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Use defaults from ~/.azwork.yml
|
|
68
|
+
azwork
|
|
69
|
+
|
|
70
|
+
# Override org and project
|
|
71
|
+
azwork --org myorg --project myproject
|
|
72
|
+
|
|
73
|
+
# Custom export directory
|
|
74
|
+
azwork --output-dir ./sprint-bugs
|
|
75
|
+
|
|
76
|
+
# Re-run setup
|
|
77
|
+
azwork --setup
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Configuration
|
|
81
|
+
|
|
82
|
+
azwork reads its configuration from `~/.azwork.yml`. CLI arguments always take priority.
|
|
83
|
+
|
|
84
|
+
### `~/.azwork.yml` anatomy
|
|
85
|
+
|
|
86
|
+
```yaml
|
|
87
|
+
# Azure DevOps organization name (the {org} part of dev.azure.com/{org})
|
|
88
|
+
org: myorg
|
|
89
|
+
|
|
90
|
+
# Project name within the organization
|
|
91
|
+
project: myproject
|
|
92
|
+
|
|
93
|
+
# Default directory where exported Markdown files are saved.
|
|
94
|
+
# Can be an absolute path or relative to where you run azwork.
|
|
95
|
+
# Created automatically on first export if it doesn't exist.
|
|
96
|
+
default_output_dir: ./bugs
|
|
97
|
+
|
|
98
|
+
# Work item types to include in queries.
|
|
99
|
+
# These are used both as WIQL filter and as options in the Type dropdown.
|
|
100
|
+
# Common values: Bug, Task, User Story, Epic, Feature, Issue, Test Case
|
|
101
|
+
work_item_types:
|
|
102
|
+
- Bug
|
|
103
|
+
- Task
|
|
104
|
+
- User Story
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
All fields are optional when using CLI overrides. The PAT is **never** stored in the config file — it is always read from the `AZURE_DEVOPS_PAT` environment variable.
|
|
108
|
+
|
|
109
|
+
### Minimal example
|
|
110
|
+
|
|
111
|
+
```yaml
|
|
112
|
+
org: contoso
|
|
113
|
+
project: webapp
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Full example
|
|
117
|
+
|
|
118
|
+
```yaml
|
|
119
|
+
org: contoso
|
|
120
|
+
project: webapp
|
|
121
|
+
default_output_dir: ~/work/bugs
|
|
122
|
+
work_item_types:
|
|
123
|
+
- Bug
|
|
124
|
+
- Task
|
|
125
|
+
- User Story
|
|
126
|
+
- Feature
|
|
127
|
+
- Epic
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Keybindings
|
|
131
|
+
|
|
132
|
+
### List screen
|
|
133
|
+
|
|
134
|
+
| Key | Action |
|
|
135
|
+
|-----|--------|
|
|
136
|
+
| `↑` `↓` | Navigate rows |
|
|
137
|
+
| `Enter` | Open detail view |
|
|
138
|
+
| `E` | Export highlighted item to Markdown |
|
|
139
|
+
| `R` | Refresh (re-fetch from API) |
|
|
140
|
+
| `Q` | Quit |
|
|
141
|
+
| `?` | Show help |
|
|
142
|
+
|
|
143
|
+
Column headers are clickable to sort by that column.
|
|
144
|
+
|
|
145
|
+
### Detail screen
|
|
146
|
+
|
|
147
|
+
| Key | Action |
|
|
148
|
+
|-----|--------|
|
|
149
|
+
| `Esc` | Back to list |
|
|
150
|
+
| `E` | Export as Markdown |
|
|
151
|
+
| `P` | Export as Claude Code prompt |
|
|
152
|
+
| `C` | Copy Markdown to clipboard |
|
|
153
|
+
| `O` | Open in browser |
|
|
154
|
+
| `?` | Show help |
|
|
155
|
+
|
|
156
|
+
## Export formats
|
|
157
|
+
|
|
158
|
+
### Markdown
|
|
159
|
+
|
|
160
|
+
A structured Markdown file with metadata table, description, repro steps, acceptance criteria, discussion thread, related items, and custom fields.
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
bugs/1234-login-fails-special-chars.md
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Claude Code prompt
|
|
167
|
+
|
|
168
|
+
Same Markdown content wrapped in a prompt template that instructs Claude Code to analyze and resolve the work item:
|
|
169
|
+
|
|
170
|
+
```markdown
|
|
171
|
+
# Task: Resolve the following work item
|
|
172
|
+
|
|
173
|
+
Analyze the work item described below and take the necessary actions to resolve it.
|
|
174
|
+
The project context is described in the CLAUDE.md file at the repository root.
|
|
175
|
+
|
|
176
|
+
## Work Item
|
|
177
|
+
[... full work item markdown ...]
|
|
178
|
+
|
|
179
|
+
## Instructions
|
|
180
|
+
1. Analyze the work item and identify the affected files
|
|
181
|
+
2. Implement the fix or the requested feature
|
|
182
|
+
3. Write or update tests to cover the case
|
|
183
|
+
4. Verify that existing tests are not broken
|
|
184
|
+
5. Briefly describe the changes you made
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Project structure
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
azwork/
|
|
191
|
+
├── __main__.py # CLI entry point (argparse)
|
|
192
|
+
├── config.py # YAML config loading + CLI merge
|
|
193
|
+
├── utils.py # HTML→Markdown conversion
|
|
194
|
+
├── api/
|
|
195
|
+
│ ├── client.py # Azure DevOps REST client (auth, batching, cache)
|
|
196
|
+
│ ├── wiql.py # WIQL query builder
|
|
197
|
+
│ └── models.py # WorkItem, Comment, Relation dataclasses
|
|
198
|
+
├── tui/
|
|
199
|
+
│ ├── app.py # Textual App
|
|
200
|
+
│ ├── screens/
|
|
201
|
+
│ │ ├── list_screen.py # Work item list with filters
|
|
202
|
+
│ │ └── detail_screen.py # Single item detail + export dialog
|
|
203
|
+
│ └── widgets/
|
|
204
|
+
│ ├── filter_bar.py # Type / State / Iteration / Search filters
|
|
205
|
+
│ └── item_table.py # Sortable DataTable for work items
|
|
206
|
+
└── export/
|
|
207
|
+
├── markdown.py # Markdown generation
|
|
208
|
+
└── prompt.py # Claude Code prompt wrapper
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Running tests
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
pytest
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Tests mock all API calls and cover:
|
|
218
|
+
|
|
219
|
+
- API client (pagination, HTTP errors, caching, response parsing)
|
|
220
|
+
- WIQL query construction with various filter combinations
|
|
221
|
+
- Markdown export (formatting, edge cases, empty fields)
|
|
222
|
+
- HTML → Markdown conversion (all supported tags)
|
|
223
|
+
|
|
224
|
+
## Requirements
|
|
225
|
+
|
|
226
|
+
- Python 3.10+
|
|
227
|
+
- An Azure DevOps organization with work items
|
|
228
|
+
- A PAT with **Work Items → Read** scope
|
|
229
|
+
|
|
230
|
+
## License
|
|
231
|
+
|
|
232
|
+
MIT
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""CLI entry point for azwork."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from azwork.config import Config, CONFIG_PATH
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main() -> None:
|
|
12
|
+
parser = argparse.ArgumentParser(
|
|
13
|
+
prog="azwork",
|
|
14
|
+
description="TUI for triaging Azure DevOps work items",
|
|
15
|
+
)
|
|
16
|
+
parser.add_argument("--org", help="Azure DevOps organization")
|
|
17
|
+
parser.add_argument("--project", help="Azure DevOps project")
|
|
18
|
+
parser.add_argument("--output-dir", help="Default output directory for exports")
|
|
19
|
+
parser.add_argument("--setup", action="store_true", help="Run setup wizard")
|
|
20
|
+
|
|
21
|
+
args = parser.parse_args()
|
|
22
|
+
|
|
23
|
+
if args.setup:
|
|
24
|
+
_run_setup()
|
|
25
|
+
return
|
|
26
|
+
|
|
27
|
+
config = Config.load(
|
|
28
|
+
cli_org=args.org,
|
|
29
|
+
cli_project=args.project,
|
|
30
|
+
cli_output_dir=args.output_dir,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# If no config exists and no CLI args, run setup
|
|
34
|
+
if not config.org or not config.project:
|
|
35
|
+
if not CONFIG_PATH.exists():
|
|
36
|
+
print("No configuration found. Running setup wizard...")
|
|
37
|
+
_run_setup()
|
|
38
|
+
config = Config.load(
|
|
39
|
+
cli_org=args.org,
|
|
40
|
+
cli_project=args.project,
|
|
41
|
+
cli_output_dir=args.output_dir,
|
|
42
|
+
)
|
|
43
|
+
else:
|
|
44
|
+
errors = config.validate()
|
|
45
|
+
for err in errors:
|
|
46
|
+
print(f"Error: {err}", file=sys.stderr)
|
|
47
|
+
sys.exit(1)
|
|
48
|
+
|
|
49
|
+
errors = config.validate()
|
|
50
|
+
if errors:
|
|
51
|
+
for err in errors:
|
|
52
|
+
print(f"Error: {err}", file=sys.stderr)
|
|
53
|
+
sys.exit(1)
|
|
54
|
+
|
|
55
|
+
from azwork.tui.app import AzworkApp
|
|
56
|
+
|
|
57
|
+
app = AzworkApp(config)
|
|
58
|
+
app.run()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _run_setup() -> None:
|
|
62
|
+
"""Interactive setup wizard to create ~/.azwork.yml."""
|
|
63
|
+
print("=== azwork Setup ===\n")
|
|
64
|
+
|
|
65
|
+
org = input("Azure DevOps Organization: ").strip()
|
|
66
|
+
project = input("Project name: ").strip()
|
|
67
|
+
output_dir = input("Default export directory [./bugs]: ").strip() or "./bugs"
|
|
68
|
+
types_input = input("Work item types (comma-separated) [Bug,Task,User Story]: ").strip()
|
|
69
|
+
types = [t.strip() for t in types_input.split(",")] if types_input else ["Bug", "Task", "User Story"]
|
|
70
|
+
|
|
71
|
+
config = Config(
|
|
72
|
+
org=org,
|
|
73
|
+
project=project,
|
|
74
|
+
default_output_dir=output_dir,
|
|
75
|
+
work_item_types=types,
|
|
76
|
+
)
|
|
77
|
+
config.save_default()
|
|
78
|
+
print(f"\nConfiguration saved to {CONFIG_PATH}")
|
|
79
|
+
print("Set AZURE_DEVOPS_PAT environment variable with your Personal Access Token.")
|
|
80
|
+
print("Run 'azwork' to start.")
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
if __name__ == "__main__":
|
|
84
|
+
main()
|
|
File without changes
|