@sppg2001/atomize 1.2.4 → 2.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/.env.example +3 -0
- package/README.md +48 -36
- package/dist/cli/index.js +22729 -28745
- package/docs/Auth-Guide.md +257 -0
- package/docs/Cli-Reference.md +959 -0
- package/docs/Common-Validation-Errors.md +556 -0
- package/docs/Getting-Started.md +540 -0
- package/docs/Platform-Guide.md +662 -0
- package/docs/Story-Learner.md +324 -0
- package/docs/Template-Reference.md +743 -0
- package/docs/Validation-Modes.md +252 -0
- package/docs/template-wizard-guide.md +738 -0
- package/examples/README.md +16 -11
- package/examples/advanced-filtering.yaml +1 -1
- package/examples/conditional-dependencies-template.yaml +28 -5
- package/examples/conditional-percentage-template.yaml +39 -11
- package/examples/fullstack.yaml +4 -1
- package/package.json +23 -14
- package/templates/mixins/docs.yaml +16 -0
- package/templates/mixins/security.yaml +16 -0
- package/templates/mixins/testing.yaml +27 -0
- package/templates/templates/bug.yaml +54 -0
- package/templates/templates/custom-saved-query.yaml +214 -0
- package/templates/{presets → templates}/custom.yaml +100 -15
- package/templates/templates/feature.yaml +55 -0
- package/templates/presets/bug-fix.yaml +0 -44
- package/templates/presets/frontend-feature.yaml +0 -52
- /package/templates/{presets → templates}/backend-api.yaml +0 -0
package/examples/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Examples
|
|
2
2
|
|
|
3
|
-
Real-world Atomize template examples. Each file is a working template you can validate and run
|
|
3
|
+
Real-world Atomize template examples. Each file is a working template you can validate immediately and dry-run against either matching work items or explicit mock stories.
|
|
4
4
|
|
|
5
5
|
## Files
|
|
6
6
|
|
|
@@ -32,7 +32,7 @@ A production-ready backend API template. Covers the full development cycle from
|
|
|
32
32
|
**Try it:**
|
|
33
33
|
```bash
|
|
34
34
|
atomize validate examples/backend.yaml
|
|
35
|
-
atomize generate examples/backend.yaml --platform mock
|
|
35
|
+
atomize generate examples/backend.yaml --platform mock
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
---
|
|
@@ -54,7 +54,7 @@ A React component development template covering the full UI lifecycle including
|
|
|
54
54
|
**Try it:**
|
|
55
55
|
```bash
|
|
56
56
|
atomize validate examples/frontend.yaml
|
|
57
|
-
atomize generate examples/frontend.yaml --platform mock
|
|
57
|
+
atomize generate examples/frontend.yaml --platform mock
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
---
|
|
@@ -79,7 +79,7 @@ A combined backend + frontend template for end-to-end features. Uses a branching
|
|
|
79
79
|
**Try it:**
|
|
80
80
|
```bash
|
|
81
81
|
atomize validate examples/fullstack.yaml
|
|
82
|
-
atomize generate examples/fullstack.yaml --platform mock --
|
|
82
|
+
atomize generate examples/fullstack.yaml --platform mock --story STORY-004
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
---
|
|
@@ -114,7 +114,7 @@ Demonstrates **conditional tasks** — tasks that are only created when a story
|
|
|
114
114
|
**Try it:**
|
|
115
115
|
```bash
|
|
116
116
|
atomize validate examples/conditional-dependencies-template.yaml
|
|
117
|
-
atomize generate examples/conditional-dependencies-template.yaml --platform mock --
|
|
117
|
+
atomize generate examples/conditional-dependencies-template.yaml --platform mock --story STORY-004
|
|
118
118
|
```
|
|
119
119
|
|
|
120
120
|
---
|
|
@@ -155,7 +155,7 @@ All totals are normalized to exactly 100% at generation time.
|
|
|
155
155
|
**Try it:**
|
|
156
156
|
```bash
|
|
157
157
|
atomize validate examples/conditional-percentage-template.yaml
|
|
158
|
-
atomize generate examples/conditional-percentage-template.yaml --platform mock
|
|
158
|
+
atomize generate examples/conditional-percentage-template.yaml --platform mock
|
|
159
159
|
```
|
|
160
160
|
|
|
161
161
|
---
|
|
@@ -168,7 +168,7 @@ A reference template that demonstrates every available filter option. Use it as
|
|
|
168
168
|
|
|
169
169
|
| Filter | What it does |
|
|
170
170
|
|--------|-------------|
|
|
171
|
-
| `team` | Overrides the
|
|
171
|
+
| `team` | Overrides the team from the selected Azure DevOps profile for this template |
|
|
172
172
|
| `statesExclude` | Excludes items in `Done`, `Removed`, or `Won't Fix` |
|
|
173
173
|
| `statesWereEver` | Matches items that passed through `In Review` historically |
|
|
174
174
|
| `areaPathsUnder` | Matches `MyProject\Backend` **and all sub-areas** (hierarchy traversal) |
|
|
@@ -185,7 +185,7 @@ A reference template that demonstrates every available filter option. Use it as
|
|
|
185
185
|
**Try it:**
|
|
186
186
|
```bash
|
|
187
187
|
atomize validate examples/advanced-filtering.yaml
|
|
188
|
-
atomize generate examples/advanced-filtering.yaml --platform mock --
|
|
188
|
+
atomize generate examples/advanced-filtering.yaml --platform mock --story STORY-001
|
|
189
189
|
```
|
|
190
190
|
|
|
191
191
|
---
|
|
@@ -199,11 +199,16 @@ for f in examples/*.yaml; do
|
|
|
199
199
|
atomize validate "$f"
|
|
200
200
|
done
|
|
201
201
|
|
|
202
|
-
#
|
|
203
|
-
for f in examples
|
|
202
|
+
# Dry-run examples that match the bundled mock filters
|
|
203
|
+
for f in examples/backend.yaml examples/frontend.yaml examples/conditional-percentage-template.yaml; do
|
|
204
204
|
echo "Testing $f..."
|
|
205
|
-
atomize generate "$f" --platform mock
|
|
205
|
+
atomize generate "$f" --platform mock
|
|
206
206
|
done
|
|
207
|
+
|
|
208
|
+
# Dry-run examples whose filters are intentionally more specific than the mock dataset
|
|
209
|
+
atomize generate examples/fullstack.yaml --platform mock --story STORY-004
|
|
210
|
+
atomize generate examples/conditional-dependencies-template.yaml --platform mock --story STORY-004
|
|
211
|
+
atomize generate examples/advanced-filtering.yaml --platform mock --story STORY-001
|
|
207
212
|
```
|
|
208
213
|
|
|
209
214
|
---
|
|
@@ -10,7 +10,7 @@ tags: ["demo", "filtering", "advanced"]
|
|
|
10
10
|
# Each option below is independent — in a real template you would only use
|
|
11
11
|
# the subset that makes sense for your workflow.
|
|
12
12
|
filter:
|
|
13
|
-
# Override the team
|
|
13
|
+
# Override the team from the selected Azure DevOps profile
|
|
14
14
|
team: "Backend Team"
|
|
15
15
|
|
|
16
16
|
workItemTypes:
|
|
@@ -31,7 +31,10 @@ tasks:
|
|
|
31
31
|
estimationPercent: 30
|
|
32
32
|
activity: "Development"
|
|
33
33
|
dependsOn: ["design"]
|
|
34
|
-
condition:
|
|
34
|
+
condition:
|
|
35
|
+
field: tags
|
|
36
|
+
operator: contains
|
|
37
|
+
value: backend
|
|
35
38
|
tags:
|
|
36
39
|
- "backend"
|
|
37
40
|
- "api"
|
|
@@ -43,7 +46,10 @@ tasks:
|
|
|
43
46
|
estimationPercent: 35
|
|
44
47
|
activity: "Development"
|
|
45
48
|
dependsOn: ["design"]
|
|
46
|
-
condition:
|
|
49
|
+
condition:
|
|
50
|
+
field: tags
|
|
51
|
+
operator: contains
|
|
52
|
+
value: frontend
|
|
47
53
|
tags:
|
|
48
54
|
- "frontend"
|
|
49
55
|
|
|
@@ -54,7 +60,14 @@ tasks:
|
|
|
54
60
|
estimationPercent: 7
|
|
55
61
|
activity: "Testing"
|
|
56
62
|
dependsOn: ["frontend-ui"]
|
|
57
|
-
condition:
|
|
63
|
+
condition:
|
|
64
|
+
any:
|
|
65
|
+
- field: tags
|
|
66
|
+
operator: contains
|
|
67
|
+
value: frontend
|
|
68
|
+
- field: tags
|
|
69
|
+
operator: not-contains
|
|
70
|
+
value: legacy
|
|
58
71
|
tags:
|
|
59
72
|
- "accessibility"
|
|
60
73
|
- "testing"
|
|
@@ -66,7 +79,14 @@ tasks:
|
|
|
66
79
|
estimationPercent: 8
|
|
67
80
|
activity: "Testing"
|
|
68
81
|
dependsOn: ["backend-api", "frontend-ui"]
|
|
69
|
-
condition:
|
|
82
|
+
condition:
|
|
83
|
+
all:
|
|
84
|
+
- field: tags
|
|
85
|
+
operator: contains
|
|
86
|
+
value: security
|
|
87
|
+
- field: priority
|
|
88
|
+
operator: lte
|
|
89
|
+
value: 2
|
|
70
90
|
priority: 1
|
|
71
91
|
tags:
|
|
72
92
|
- "security"
|
|
@@ -97,7 +117,10 @@ tasks:
|
|
|
97
117
|
estimationPercent: 10
|
|
98
118
|
activity: "Testing"
|
|
99
119
|
dependsOn: ["integration-tests"]
|
|
100
|
-
condition:
|
|
120
|
+
condition:
|
|
121
|
+
field: estimation
|
|
122
|
+
operator: gte
|
|
123
|
+
value: 13
|
|
101
124
|
tags:
|
|
102
125
|
- "performance"
|
|
103
126
|
|
|
@@ -31,9 +31,15 @@ tasks:
|
|
|
31
31
|
assignTo: "@ParentAssignee"
|
|
32
32
|
estimationPercent: 10
|
|
33
33
|
estimationPercentCondition:
|
|
34
|
-
- condition:
|
|
34
|
+
- condition:
|
|
35
|
+
field: estimation
|
|
36
|
+
operator: gte
|
|
37
|
+
value: 13
|
|
35
38
|
percent: 20
|
|
36
|
-
- condition:
|
|
39
|
+
- condition:
|
|
40
|
+
field: estimation
|
|
41
|
+
operator: gte
|
|
42
|
+
value: 5
|
|
37
43
|
percent: 15
|
|
38
44
|
tags: ["design"]
|
|
39
45
|
|
|
@@ -51,9 +57,15 @@ tasks:
|
|
|
51
57
|
dependsOn: ["design"]
|
|
52
58
|
estimationPercent: 60
|
|
53
59
|
estimationPercentCondition:
|
|
54
|
-
- condition:
|
|
60
|
+
- condition:
|
|
61
|
+
field: tags
|
|
62
|
+
operator: contains
|
|
63
|
+
value: fullstack
|
|
55
64
|
percent: 40
|
|
56
|
-
- condition:
|
|
65
|
+
- condition:
|
|
66
|
+
field: estimation
|
|
67
|
+
operator: gte
|
|
68
|
+
value: 5
|
|
57
69
|
percent: 50
|
|
58
70
|
tags: ["backend"]
|
|
59
71
|
|
|
@@ -70,10 +82,16 @@ tasks:
|
|
|
70
82
|
activity: "Development"
|
|
71
83
|
assignTo: "@ParentAssignee"
|
|
72
84
|
dependsOn: ["design"]
|
|
73
|
-
condition:
|
|
85
|
+
condition:
|
|
86
|
+
field: tags
|
|
87
|
+
operator: contains
|
|
88
|
+
value: fullstack
|
|
74
89
|
estimationPercent: 30
|
|
75
90
|
estimationPercentCondition:
|
|
76
|
-
- condition:
|
|
91
|
+
- condition:
|
|
92
|
+
field: tags
|
|
93
|
+
operator: contains
|
|
94
|
+
value: complex-ui
|
|
77
95
|
percent: 40
|
|
78
96
|
tags: ["frontend"]
|
|
79
97
|
|
|
@@ -90,9 +108,19 @@ tasks:
|
|
|
90
108
|
dependsOn: ["backend-impl"]
|
|
91
109
|
estimationPercent: 20
|
|
92
110
|
estimationPercentCondition:
|
|
93
|
-
- condition:
|
|
111
|
+
- condition:
|
|
112
|
+
all:
|
|
113
|
+
- field: tags
|
|
114
|
+
operator: contains
|
|
115
|
+
value: critical
|
|
116
|
+
- field: estimation
|
|
117
|
+
operator: gte
|
|
118
|
+
value: 8
|
|
94
119
|
percent: 30
|
|
95
|
-
- condition:
|
|
120
|
+
- condition:
|
|
121
|
+
field: tags
|
|
122
|
+
operator: contains
|
|
123
|
+
value: critical
|
|
96
124
|
percent: 25
|
|
97
125
|
tags: ["testing"]
|
|
98
126
|
|
|
@@ -120,13 +148,13 @@ metadata:
|
|
|
120
148
|
|
|
121
149
|
Scenario A — small backend-only story (< 5 pts, no "fullstack" tag):
|
|
122
150
|
design=10 backend=60 testing=20 review=5 → total=95 → normalised to 100
|
|
123
|
-
Scenario B — medium backend-only story (5
|
|
151
|
+
Scenario B — medium backend-only story (5/12 pts):
|
|
124
152
|
design=15 backend=50 testing=20 review=5 → total=90 → normalised to 100
|
|
125
|
-
Scenario C — medium fullstack story (5
|
|
153
|
+
Scenario C — medium fullstack story (5/12 pts, "fullstack" tag):
|
|
126
154
|
design=15 backend=40 frontend=30 testing=20 review=5 → total=110 → normalised
|
|
127
155
|
Scenario D — large critical fullstack story (≥ 13 pts, "critical" + "fullstack" tags):
|
|
128
156
|
design=20 backend=40 frontend=30 testing=30 review=5 → total=125 → normalised
|
|
129
|
-
Scenario E — medium critical backend-only story (5
|
|
157
|
+
Scenario E — medium critical backend-only story (5/12 pts, "critical", no "fullstack"):
|
|
130
158
|
design=15 backend=50 testing=25 review=5 → total=95 → normalised to 100
|
|
131
159
|
|
|
132
160
|
Key behaviour: when frontend-impl is skipped (no "fullstack" tag) the
|
package/examples/fullstack.yaml
CHANGED
|
@@ -54,7 +54,10 @@ tasks:
|
|
|
54
54
|
estimationPercent: 15
|
|
55
55
|
tags: ["database", "backend"]
|
|
56
56
|
activity: "Development"
|
|
57
|
-
condition:
|
|
57
|
+
condition:
|
|
58
|
+
field: tags
|
|
59
|
+
operator: contains
|
|
60
|
+
value: database
|
|
58
61
|
|
|
59
62
|
- id: "backend-tests"
|
|
60
63
|
title: "Backend Tests"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sppg2001/atomize",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Automatically generate tasks from user stories with smart templates",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cli/index.js",
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
|
-
"templates/
|
|
17
|
+
"templates/templates",
|
|
18
|
+
"templates/mixins",
|
|
19
|
+
"docs",
|
|
18
20
|
"README.md",
|
|
19
21
|
"LICENSE",
|
|
20
22
|
".env.example",
|
|
@@ -33,6 +35,7 @@
|
|
|
33
35
|
"test:watch": "bun test --watch",
|
|
34
36
|
"test:coverage": "bun test --coverage --coverage-reporter=lcov",
|
|
35
37
|
"typecheck": "tsc --noEmit",
|
|
38
|
+
"audit": "bun audit --audit-level=moderate",
|
|
36
39
|
"validate": "bun run src/cli/index.ts validate",
|
|
37
40
|
"validate:package": "node ./scripts/validate-package.mjs",
|
|
38
41
|
"check": "bun typecheck && bun test",
|
|
@@ -62,27 +65,33 @@
|
|
|
62
65
|
"author": "Simão Pereira Gomes",
|
|
63
66
|
"license": "MIT",
|
|
64
67
|
"devDependencies": {
|
|
65
|
-
"@biomejs/biome": "2.
|
|
66
|
-
"@types/bun": "1.3.
|
|
68
|
+
"@biomejs/biome": "2.4.12",
|
|
69
|
+
"@types/bun": "1.3.13",
|
|
67
70
|
"@types/keytar": "^4.4.2",
|
|
68
|
-
"@types/node": "^25.0
|
|
69
|
-
"@types/
|
|
70
|
-
"
|
|
71
|
+
"@types/node": "^25.6.0",
|
|
72
|
+
"@types/semver": "^7.7.1",
|
|
73
|
+
"bun-types": "^1.3.13",
|
|
74
|
+
"mitata": "^1.0.34",
|
|
75
|
+
"typescript": "^6.0.3"
|
|
71
76
|
},
|
|
72
77
|
"peerDependencies": {
|
|
73
|
-
"typescript": "^
|
|
78
|
+
"typescript": "^6.0.3"
|
|
74
79
|
},
|
|
75
80
|
"dependencies": {
|
|
76
|
-
"@clack/prompts": "^1.
|
|
81
|
+
"@clack/prompts": "^1.2.0",
|
|
77
82
|
"azure-devops-node-api": "^15.1.2",
|
|
78
83
|
"chalk": "^5.6.2",
|
|
79
|
-
"commander": "^14.0.
|
|
84
|
+
"commander": "^14.0.3",
|
|
80
85
|
"keytar": "^7.9.0",
|
|
86
|
+
"openai": "^6.34.0",
|
|
87
|
+
"semver": "^7.7.4",
|
|
81
88
|
"ts-pattern": "^5.9.0",
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
|
|
85
|
-
|
|
89
|
+
"yaml": "^2.8.3",
|
|
90
|
+
"zod": "^4.3.6"
|
|
91
|
+
},
|
|
92
|
+
"overrides": {
|
|
93
|
+
"qs": "6.15.1",
|
|
94
|
+
"underscore": "1.13.8"
|
|
86
95
|
},
|
|
87
96
|
"engines": {
|
|
88
97
|
"node": ">=18.0.0"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: "Documentation Mixin"
|
|
2
|
+
description: "Standard documentation tasks. Mix into any template to ensure docs are part of the definition of done."
|
|
3
|
+
tasks:
|
|
4
|
+
- id: "update-docs"
|
|
5
|
+
title: "Update Documentation: ${story.title}"
|
|
6
|
+
description: "Update or create user-facing documentation, API docs, and README files to reflect the changes."
|
|
7
|
+
estimationPercent: 10
|
|
8
|
+
activity: "Documentation"
|
|
9
|
+
assignTo: "@Unassigned"
|
|
10
|
+
|
|
11
|
+
- id: "changelog-entry"
|
|
12
|
+
title: "Add Changelog Entry: ${story.title}"
|
|
13
|
+
description: "Add a clear, user-focused entry to the project changelog describing what changed and why."
|
|
14
|
+
estimationPercent: 5
|
|
15
|
+
activity: "Documentation"
|
|
16
|
+
assignTo: "@ParentAssignee"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: "Security Mixin"
|
|
2
|
+
description: "Common security review tasks. Mix into any feature template to enforce a security gate."
|
|
3
|
+
tasks:
|
|
4
|
+
- id: "security-review"
|
|
5
|
+
title: "Security Review: ${story.title}"
|
|
6
|
+
description: "Review the implementation for security vulnerabilities (OWASP Top 10, input validation, auth/authz, secrets handling)."
|
|
7
|
+
estimationPercent: 10
|
|
8
|
+
activity: "Design"
|
|
9
|
+
assignTo: "@Unassigned"
|
|
10
|
+
|
|
11
|
+
- id: "dependency-audit"
|
|
12
|
+
title: "Dependency Audit: ${story.title}"
|
|
13
|
+
description: "Audit third-party dependencies for known vulnerabilities (e.g. npm audit, OWASP Dependency-Check)."
|
|
14
|
+
estimationPercent: 5
|
|
15
|
+
activity: "Development"
|
|
16
|
+
assignTo: "@Unassigned"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: "Testing Mixin"
|
|
2
|
+
description: "Expanded testing tasks. Mix into any template to enforce unit, integration, and E2E test coverage."
|
|
3
|
+
tasks:
|
|
4
|
+
- id: "unit-tests"
|
|
5
|
+
title: "Unit Tests: ${story.title}"
|
|
6
|
+
description: "Write unit tests covering the core logic and edge cases. Aim for ≥80% coverage on changed code."
|
|
7
|
+
estimationPercent: 15
|
|
8
|
+
activity: "Testing"
|
|
9
|
+
assignTo: "@ParentAssignee"
|
|
10
|
+
|
|
11
|
+
- id: "integration-tests"
|
|
12
|
+
title: "Integration Tests: ${story.title}"
|
|
13
|
+
description: "Write integration tests covering interactions between components, APIs, and external dependencies."
|
|
14
|
+
estimationPercent: 10
|
|
15
|
+
activity: "Testing"
|
|
16
|
+
dependsOn: ["unit-tests"]
|
|
17
|
+
|
|
18
|
+
- id: "e2e-tests"
|
|
19
|
+
title: "End-to-End Tests: ${story.title}"
|
|
20
|
+
description: "Validate the full user journey through the feature using E2E test scenarios."
|
|
21
|
+
estimationPercent: 10
|
|
22
|
+
activity: "Testing"
|
|
23
|
+
assignTo: "@Unassigned"
|
|
24
|
+
condition:
|
|
25
|
+
field: "tags"
|
|
26
|
+
operator: "contains"
|
|
27
|
+
value: "e2e"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
version: "1.0"
|
|
2
|
+
name: "Bug Template"
|
|
3
|
+
description: "Foundation for bug-fix templates. Extend this to inherit a standard investigation and fix task set."
|
|
4
|
+
author: "Atomize"
|
|
5
|
+
tags: ["template", "bug"]
|
|
6
|
+
|
|
7
|
+
filter:
|
|
8
|
+
workItemTypes: ["Bug"]
|
|
9
|
+
states: ["New", "Active", "Committed"]
|
|
10
|
+
excludeIfHasTasks: true
|
|
11
|
+
|
|
12
|
+
tasks:
|
|
13
|
+
- id: "investigate"
|
|
14
|
+
title: "Investigate: ${story.title}"
|
|
15
|
+
description: "Reproduce the bug, identify the root cause, and document findings."
|
|
16
|
+
estimationPercent: 30
|
|
17
|
+
activity: "Requirements"
|
|
18
|
+
assignTo: "@ParentAssignee"
|
|
19
|
+
estimationPercentCondition:
|
|
20
|
+
- condition:
|
|
21
|
+
field: "Priority"
|
|
22
|
+
operator: "lte"
|
|
23
|
+
value: 2
|
|
24
|
+
percent: 40
|
|
25
|
+
|
|
26
|
+
- id: "fix"
|
|
27
|
+
title: "Fix: ${story.title}"
|
|
28
|
+
description: "Implement the fix for the identified root cause."
|
|
29
|
+
estimationPercent: 40
|
|
30
|
+
activity: "Development"
|
|
31
|
+
assignTo: "@ParentAssignee"
|
|
32
|
+
dependsOn: ["investigate"]
|
|
33
|
+
|
|
34
|
+
- id: "verify"
|
|
35
|
+
title: "Verify Fix: ${story.title}"
|
|
36
|
+
description: "Verify the fix resolves the issue and does not introduce regressions."
|
|
37
|
+
estimationPercent: 20
|
|
38
|
+
activity: "Testing"
|
|
39
|
+
dependsOn: ["fix"]
|
|
40
|
+
|
|
41
|
+
- id: "close"
|
|
42
|
+
title: "Close & Document: ${story.title}"
|
|
43
|
+
description: "Update documentation, close the bug, and notify stakeholders."
|
|
44
|
+
estimationPercent: 10
|
|
45
|
+
activity: "Documentation"
|
|
46
|
+
dependsOn: ["verify"]
|
|
47
|
+
|
|
48
|
+
estimation:
|
|
49
|
+
strategy: "percentage"
|
|
50
|
+
rounding: "none"
|
|
51
|
+
ifParentHasNoEstimation: "warn"
|
|
52
|
+
|
|
53
|
+
validation:
|
|
54
|
+
totalEstimationMustBe: 100
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
version: "1.0"
|
|
2
|
+
name: "Custom Example — Saved Query"
|
|
3
|
+
description: "Same task breakdown as the custom example, but work item selection is delegated to an existing Azure DevOps saved query instead of a structured filter. Useful when your team already maintains a query that encodes complex area path, iteration, and tag logic."
|
|
4
|
+
author: "Atomize"
|
|
5
|
+
tags: []
|
|
6
|
+
|
|
7
|
+
filter:
|
|
8
|
+
savedQuery:
|
|
9
|
+
path: "Shared Queries/Teams/Platform/Ready for Sprint"
|
|
10
|
+
excludeIfHasTasks: true
|
|
11
|
+
|
|
12
|
+
tasks:
|
|
13
|
+
- title: "Analysis & Playback"
|
|
14
|
+
estimationPercent: 20
|
|
15
|
+
activity: "Development"
|
|
16
|
+
tags: []
|
|
17
|
+
assignTo: "@ParentAssignee"
|
|
18
|
+
condition:
|
|
19
|
+
all:
|
|
20
|
+
- field: tags
|
|
21
|
+
operator: not-contains
|
|
22
|
+
value: Testing Only
|
|
23
|
+
- field: tags
|
|
24
|
+
operator: not-contains
|
|
25
|
+
value: Test Only
|
|
26
|
+
|
|
27
|
+
- title: "Build"
|
|
28
|
+
estimationPercent: 50
|
|
29
|
+
activity: "Development"
|
|
30
|
+
tags: []
|
|
31
|
+
assignTo: "@ParentAssignee"
|
|
32
|
+
condition:
|
|
33
|
+
all:
|
|
34
|
+
- field: tags
|
|
35
|
+
operator: not-contains
|
|
36
|
+
value: Testing Only
|
|
37
|
+
- field: tags
|
|
38
|
+
operator: not-contains
|
|
39
|
+
value: Test Only
|
|
40
|
+
|
|
41
|
+
- title: "Developer Test"
|
|
42
|
+
estimationPercent: 25
|
|
43
|
+
activity: "Development"
|
|
44
|
+
tags: []
|
|
45
|
+
assignTo: "@ParentAssignee"
|
|
46
|
+
condition:
|
|
47
|
+
all:
|
|
48
|
+
- field: tags
|
|
49
|
+
operator: not-contains
|
|
50
|
+
value: Testing Only
|
|
51
|
+
- field: tags
|
|
52
|
+
operator: not-contains
|
|
53
|
+
value: Test Only
|
|
54
|
+
|
|
55
|
+
- title: "QA Smoke Test"
|
|
56
|
+
estimationPercent: 0
|
|
57
|
+
activity: "Development"
|
|
58
|
+
tags: []
|
|
59
|
+
assignTo: "@ParentAssignee"
|
|
60
|
+
condition:
|
|
61
|
+
all:
|
|
62
|
+
- field: tags
|
|
63
|
+
operator: not-contains
|
|
64
|
+
value: Testing Only
|
|
65
|
+
- field: tags
|
|
66
|
+
operator: not-contains
|
|
67
|
+
value: Test Only
|
|
68
|
+
|
|
69
|
+
- title: "Wiki"
|
|
70
|
+
estimationPercent: 5
|
|
71
|
+
activity: "Development"
|
|
72
|
+
tags: []
|
|
73
|
+
assignTo: "@ParentAssignee"
|
|
74
|
+
condition:
|
|
75
|
+
all:
|
|
76
|
+
- field: tags
|
|
77
|
+
operator: not-contains
|
|
78
|
+
value: Testing Only
|
|
79
|
+
- field: tags
|
|
80
|
+
operator: not-contains
|
|
81
|
+
value: Test Only
|
|
82
|
+
|
|
83
|
+
- title: "Code Review"
|
|
84
|
+
estimationPercent: 0
|
|
85
|
+
activity: "Development"
|
|
86
|
+
tags: []
|
|
87
|
+
assignTo: "@Unassigned"
|
|
88
|
+
condition:
|
|
89
|
+
all:
|
|
90
|
+
- field: tags
|
|
91
|
+
operator: not-contains
|
|
92
|
+
value: Testing Only
|
|
93
|
+
- field: tags
|
|
94
|
+
operator: not-contains
|
|
95
|
+
value: Test Only
|
|
96
|
+
|
|
97
|
+
- title: "Physical Data Model Updated"
|
|
98
|
+
estimationPercent: 0
|
|
99
|
+
activity: "Development"
|
|
100
|
+
tags: []
|
|
101
|
+
assignTo: "@ParentAssignee"
|
|
102
|
+
condition:
|
|
103
|
+
all:
|
|
104
|
+
- field: tags
|
|
105
|
+
operator: not-contains
|
|
106
|
+
value: Testing Only
|
|
107
|
+
- field: tags
|
|
108
|
+
operator: not-contains
|
|
109
|
+
value: Test Only
|
|
110
|
+
|
|
111
|
+
- title: "Test Preparation"
|
|
112
|
+
estimationPercent: 40
|
|
113
|
+
estimationPercentCondition:
|
|
114
|
+
- condition:
|
|
115
|
+
any:
|
|
116
|
+
- field: tags
|
|
117
|
+
operator: contains
|
|
118
|
+
value: Testing Only
|
|
119
|
+
- field: tags
|
|
120
|
+
operator: contains
|
|
121
|
+
value: Test Only
|
|
122
|
+
percent: 59.70
|
|
123
|
+
activity: "Testing"
|
|
124
|
+
tags: []
|
|
125
|
+
condition:
|
|
126
|
+
field: tags
|
|
127
|
+
operator: not-contains
|
|
128
|
+
value: Dev Only
|
|
129
|
+
assignTo: "@Unassigned"
|
|
130
|
+
|
|
131
|
+
- title: "Test Execution"
|
|
132
|
+
estimationPercent: 27
|
|
133
|
+
estimationPercentCondition:
|
|
134
|
+
- condition:
|
|
135
|
+
any:
|
|
136
|
+
- field: tags
|
|
137
|
+
operator: contains
|
|
138
|
+
value: Testing Only
|
|
139
|
+
- field: tags
|
|
140
|
+
operator: contains
|
|
141
|
+
value: Test Only
|
|
142
|
+
percent: 40.30
|
|
143
|
+
activity: "Testing"
|
|
144
|
+
tags: []
|
|
145
|
+
condition:
|
|
146
|
+
field: tags
|
|
147
|
+
operator: not-contains
|
|
148
|
+
value: Dev Only
|
|
149
|
+
assignTo: "@Unassigned"
|
|
150
|
+
|
|
151
|
+
- title: "Automation Testing"
|
|
152
|
+
estimationPercent: 0
|
|
153
|
+
activity: "Test Automation"
|
|
154
|
+
tags: []
|
|
155
|
+
condition:
|
|
156
|
+
field: tags
|
|
157
|
+
operator: not-contains
|
|
158
|
+
value: Dev Only
|
|
159
|
+
assignTo: "@Unassigned"
|
|
160
|
+
|
|
161
|
+
- title: "Test Review"
|
|
162
|
+
estimationPercent: 0
|
|
163
|
+
activity: "Testing"
|
|
164
|
+
tags: []
|
|
165
|
+
condition:
|
|
166
|
+
field: tags
|
|
167
|
+
operator: not-contains
|
|
168
|
+
value: Dev Only
|
|
169
|
+
assignTo: "@Unassigned"
|
|
170
|
+
|
|
171
|
+
- title: "Release Notes"
|
|
172
|
+
estimationPercent: 0
|
|
173
|
+
activity: "Testing"
|
|
174
|
+
tags: []
|
|
175
|
+
condition:
|
|
176
|
+
field: tags
|
|
177
|
+
operator: not-contains
|
|
178
|
+
value: Dev Only
|
|
179
|
+
assignTo: "@Unassigned"
|
|
180
|
+
|
|
181
|
+
- title: "Merge to Stable"
|
|
182
|
+
estimationPercent: 10
|
|
183
|
+
activity: "Development"
|
|
184
|
+
tags: []
|
|
185
|
+
assignTo: "@ParentAssignee"
|
|
186
|
+
condition:
|
|
187
|
+
all:
|
|
188
|
+
- field: tags
|
|
189
|
+
operator: not-contains
|
|
190
|
+
value: Testing Only
|
|
191
|
+
- field: tags
|
|
192
|
+
operator: not-contains
|
|
193
|
+
value: Test Only
|
|
194
|
+
|
|
195
|
+
estimation:
|
|
196
|
+
strategy: "percentage"
|
|
197
|
+
rounding: "none"
|
|
198
|
+
minimumTaskPoints: 0
|
|
199
|
+
|
|
200
|
+
metadata:
|
|
201
|
+
category: "Agile Project"
|
|
202
|
+
recommendedFor: []
|
|
203
|
+
estimationGuidelines: |
|
|
204
|
+
Identical task breakdown to the structured-filter custom example.
|
|
205
|
+
The only difference is in the filter: work item selection is handled
|
|
206
|
+
entirely by the saved query at the configured path. The query should
|
|
207
|
+
already encode area path, iteration, and tag constraints so this
|
|
208
|
+
template stays clean. Update the savedQuery path to match your project.
|
|
209
|
+
|
|
210
|
+
Handles three story archetypes in one template:
|
|
211
|
+
- Dev and Test story (no special tag): dev tasks + test tasks, base percentages apply.
|
|
212
|
+
- Testing Only / Test Only story: dev tasks skipped; Test Preparation gets 59.70%
|
|
213
|
+
and Test Execution gets 40.30%.
|
|
214
|
+
- Dev Only story: test tasks skipped.
|