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 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
+ ![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue)
33
+ ![License](https://img.shields.io/badge/license-MIT-green)
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
+ ![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue)
6
+ ![License](https://img.shields.io/badge/license-MIT-green)
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,3 @@
1
+ """azwork — Azure DevOps Work Items TUI."""
2
+
3
+ __version__ = "0.1.0"
@@ -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