jettypod 4.4.0 → 4.4.1
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/docs/DECISIONS.md +4 -52
- package/lib/chore-classifier.js +232 -0
- package/lib/chore-taxonomy.js +172 -0
- package/package.json +1 -1
- package/skills-templates/chore-mode/SKILL.md +396 -0
- package/skills-templates/chore-mode/verification.js +255 -0
- package/skills-templates/chore-planning/SKILL.md +229 -0
- package/skills-templates/epic-planning/SKILL.md +13 -5
- package/skills-templates/feature-planning/SKILL.md +8 -3
package/docs/DECISIONS.md
CHANGED
|
@@ -6,61 +6,13 @@ This document records key decisions made during project discovery and epic plann
|
|
|
6
6
|
|
|
7
7
|
## Epic-Level Decisions
|
|
8
8
|
|
|
9
|
-
### Epic #
|
|
9
|
+
### Epic #2: Standalone Chore Workflow System
|
|
10
10
|
|
|
11
|
-
**Architecture:**
|
|
11
|
+
**Architecture:** Two-tier skill structure (chore-planning → chore-mode)
|
|
12
12
|
|
|
13
|
-
*Rationale:*
|
|
13
|
+
*Rationale:* Two-tier skill structure chosen to mirror existing feature workflow patterns. Separates planning concerns (scope, criteria, impact) from execution concerns (guidance, verification). Type-dependent test analysis balances thoroughness with pragmatism.
|
|
14
14
|
|
|
15
|
-
*Date:*
|
|
16
|
-
|
|
17
|
-
**State Management:** Redux Toolkit
|
|
18
|
-
|
|
19
|
-
*Rationale:* Need centralized state for connection status across multiple components
|
|
20
|
-
|
|
21
|
-
*Date:* 10/29/2025
|
|
22
|
-
|
|
23
|
-
**Error Handling:** Exponential backoff with jitter for reconnection
|
|
24
|
-
|
|
25
|
-
*Rationale:* Prevents thundering herd when server recovers, jitter distributes reconnection attempts evenly
|
|
26
|
-
|
|
27
|
-
*Date:* 10/31/2025
|
|
28
|
-
|
|
29
|
-
**Testing Strategy:** Integration tests with mock Socket.io server
|
|
30
|
-
|
|
31
|
-
*Rationale:* Allows testing reconnection logic and state synchronization without real server dependency
|
|
32
|
-
|
|
33
|
-
*Date:* 10/31/2025
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
### Epic #238: Real-time System
|
|
38
|
-
|
|
39
|
-
**Architecture:** WebSockets
|
|
40
|
-
|
|
41
|
-
*Rationale:* Real-time bidirectional communication required
|
|
42
|
-
|
|
43
|
-
*Date:* 10/29/2025
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
### Epic #242: Epic Needs Discovery
|
|
48
|
-
|
|
49
|
-
**Architecture:** GraphQL API
|
|
50
|
-
|
|
51
|
-
*Rationale:* Flexible querying and strong typing needed for complex data requirements
|
|
52
|
-
|
|
53
|
-
*Date:* 10/29/2025
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
### Epic #1840: Multiple AI Coding Assistant Instances
|
|
58
|
-
|
|
59
|
-
**Concurrent Merge Architecture:** Database-backed merge queue with rebase-first strategy and smart conflict resolution
|
|
60
|
-
|
|
61
|
-
*Rationale:* Multiple Claude Code instances need coordinated access to main branch. Using database as coordination point provides simple, reliable serialization without complex distributed locking. Rebase-first strategy ensures linear history and makes conflicts easier to reason about. Smart conflict resolution (auto-resolve trivial, LLM-assist complex) enables autonomous operation while escalating truly ambiguous cases. Graceful degradation ensures system never enters unrecoverable state.
|
|
62
|
-
|
|
63
|
-
*Date:* 11/14/2025
|
|
15
|
+
*Date:* 11/25/2025
|
|
64
16
|
|
|
65
17
|
---
|
|
66
18
|
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chore Classifier
|
|
3
|
+
*
|
|
4
|
+
* Classifies chore type from title/description using keyword matching.
|
|
5
|
+
* Maps to the 4 chore types defined in chore-taxonomy.js
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { CHORE_TYPES, isValidChoreType } = require('./chore-taxonomy');
|
|
9
|
+
|
|
10
|
+
// Keywords that indicate each chore type
|
|
11
|
+
const TYPE_KEYWORDS = {
|
|
12
|
+
[CHORE_TYPES.REFACTOR]: [
|
|
13
|
+
'refactor',
|
|
14
|
+
'restructure',
|
|
15
|
+
'reorganize',
|
|
16
|
+
'extract',
|
|
17
|
+
'inline',
|
|
18
|
+
'rename',
|
|
19
|
+
'move',
|
|
20
|
+
'split',
|
|
21
|
+
'consolidate',
|
|
22
|
+
'simplify',
|
|
23
|
+
'decouple',
|
|
24
|
+
'modularize'
|
|
25
|
+
],
|
|
26
|
+
[CHORE_TYPES.DEPENDENCY]: [
|
|
27
|
+
'update',
|
|
28
|
+
'upgrade',
|
|
29
|
+
'bump',
|
|
30
|
+
'migrate',
|
|
31
|
+
'dependency',
|
|
32
|
+
'dependencies',
|
|
33
|
+
'package',
|
|
34
|
+
'library',
|
|
35
|
+
'framework',
|
|
36
|
+
'version',
|
|
37
|
+
'security patch',
|
|
38
|
+
'vulnerability',
|
|
39
|
+
'npm',
|
|
40
|
+
'yarn',
|
|
41
|
+
'lodash',
|
|
42
|
+
'react',
|
|
43
|
+
'node'
|
|
44
|
+
],
|
|
45
|
+
[CHORE_TYPES.CLEANUP]: [
|
|
46
|
+
'cleanup',
|
|
47
|
+
'clean up',
|
|
48
|
+
'remove',
|
|
49
|
+
'delete',
|
|
50
|
+
'deprecate',
|
|
51
|
+
'dead code',
|
|
52
|
+
'unused',
|
|
53
|
+
'legacy',
|
|
54
|
+
'obsolete',
|
|
55
|
+
'prune',
|
|
56
|
+
'trim'
|
|
57
|
+
],
|
|
58
|
+
[CHORE_TYPES.TOOLING]: [
|
|
59
|
+
'tooling',
|
|
60
|
+
'ci',
|
|
61
|
+
'cd',
|
|
62
|
+
'pipeline',
|
|
63
|
+
'build',
|
|
64
|
+
'lint',
|
|
65
|
+
'eslint',
|
|
66
|
+
'prettier',
|
|
67
|
+
'config',
|
|
68
|
+
'configuration',
|
|
69
|
+
'script',
|
|
70
|
+
'automation',
|
|
71
|
+
'github action',
|
|
72
|
+
'workflow',
|
|
73
|
+
'jest',
|
|
74
|
+
'test setup'
|
|
75
|
+
]
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Normalize and validate input text
|
|
80
|
+
* @param {string} title - The chore title
|
|
81
|
+
* @param {string} [description] - Optional description
|
|
82
|
+
* @returns {string} - Normalized text for classification
|
|
83
|
+
* @throws {Error} - If title is invalid
|
|
84
|
+
*/
|
|
85
|
+
function normalizeInput(title, description = '') {
|
|
86
|
+
// Validate title
|
|
87
|
+
if (title === null || title === undefined) {
|
|
88
|
+
throw new Error('Chore title is required for classification');
|
|
89
|
+
}
|
|
90
|
+
if (typeof title !== 'string') {
|
|
91
|
+
throw new Error(`Chore title must be a string, got ${typeof title}`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const trimmedTitle = title.trim();
|
|
95
|
+
if (trimmedTitle.length === 0) {
|
|
96
|
+
throw new Error('Chore title cannot be empty or whitespace only');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Normalize description (coerce to string if not)
|
|
100
|
+
const normalizedDesc = description != null ? String(description).trim() : '';
|
|
101
|
+
|
|
102
|
+
return `${trimmedTitle} ${normalizedDesc}`.toLowerCase();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Escape special regex characters in a string
|
|
107
|
+
* @param {string} str - String to escape
|
|
108
|
+
* @returns {string} - Escaped string safe for regex
|
|
109
|
+
*/
|
|
110
|
+
function escapeRegex(str) {
|
|
111
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Calculate scores for all chore types
|
|
116
|
+
* @param {string} text - Normalized text to analyze
|
|
117
|
+
* @returns {Object} - Scores for each type
|
|
118
|
+
*/
|
|
119
|
+
function calculateScores(text) {
|
|
120
|
+
const scores = {};
|
|
121
|
+
for (const [type, keywords] of Object.entries(TYPE_KEYWORDS)) {
|
|
122
|
+
scores[type] = 0;
|
|
123
|
+
for (const keyword of keywords) {
|
|
124
|
+
if (text.includes(keyword.toLowerCase())) {
|
|
125
|
+
// Exact word match scores higher (escape special chars for safety)
|
|
126
|
+
const escapedKeyword = escapeRegex(keyword);
|
|
127
|
+
const wordBoundaryRegex = new RegExp(`\\b${escapedKeyword}\\b`, 'i');
|
|
128
|
+
if (wordBoundaryRegex.test(text)) {
|
|
129
|
+
scores[type] += 2;
|
|
130
|
+
} else {
|
|
131
|
+
scores[type] += 1;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return scores;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Find the winning type from scores
|
|
141
|
+
* @param {Object} scores - Scores for each type
|
|
142
|
+
* @returns {Object} - { type: string, score: number }
|
|
143
|
+
*/
|
|
144
|
+
function findWinningType(scores) {
|
|
145
|
+
let maxScore = 0;
|
|
146
|
+
let classifiedType = CHORE_TYPES.REFACTOR; // Default fallback
|
|
147
|
+
|
|
148
|
+
for (const [type, score] of Object.entries(scores)) {
|
|
149
|
+
if (score > maxScore) {
|
|
150
|
+
maxScore = score;
|
|
151
|
+
classifiedType = type;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return { type: classifiedType, score: maxScore };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Classify a chore based on its title (and optionally description)
|
|
160
|
+
* @param {string} title - The chore title
|
|
161
|
+
* @param {string} [description] - Optional description for additional context
|
|
162
|
+
* @returns {string} - One of the 4 chore types
|
|
163
|
+
* @throws {Error} - If title is invalid
|
|
164
|
+
*/
|
|
165
|
+
function classifyChoreType(title, description = '') {
|
|
166
|
+
const text = normalizeInput(title, description);
|
|
167
|
+
const scores = calculateScores(text);
|
|
168
|
+
const { type } = findWinningType(scores);
|
|
169
|
+
return type;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Determine confidence level based on score
|
|
174
|
+
* @param {number} score - The classification score
|
|
175
|
+
* @returns {string} - 'high', 'medium', or 'low'
|
|
176
|
+
*/
|
|
177
|
+
function getConfidenceLevel(score) {
|
|
178
|
+
if (score >= 4) return 'high';
|
|
179
|
+
if (score >= 2) return 'medium';
|
|
180
|
+
return 'low';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Get confidence level for a classification
|
|
185
|
+
* @param {string} title - The chore title
|
|
186
|
+
* @param {string} [description] - Optional description
|
|
187
|
+
* @returns {object} - { type: string, confidence: 'high'|'medium'|'low', score: number }
|
|
188
|
+
* @throws {Error} - If title is invalid
|
|
189
|
+
*/
|
|
190
|
+
function classifyWithConfidence(title, description = '') {
|
|
191
|
+
const text = normalizeInput(title, description);
|
|
192
|
+
const scores = calculateScores(text);
|
|
193
|
+
const { type, score } = findWinningType(scores);
|
|
194
|
+
const confidence = getConfidenceLevel(score);
|
|
195
|
+
|
|
196
|
+
return { type, confidence, score };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Get detailed classification with all type scores
|
|
201
|
+
* Useful for debugging or when needing transparency in classification
|
|
202
|
+
* @param {string} title - The chore title
|
|
203
|
+
* @param {string} [description] - Optional description
|
|
204
|
+
* @returns {object} - { type, confidence, score, allScores }
|
|
205
|
+
* @throws {Error} - If title is invalid
|
|
206
|
+
*/
|
|
207
|
+
function classifyWithDetails(title, description = '') {
|
|
208
|
+
const text = normalizeInput(title, description);
|
|
209
|
+
const scores = calculateScores(text);
|
|
210
|
+
const { type, score } = findWinningType(scores);
|
|
211
|
+
const confidence = getConfidenceLevel(score);
|
|
212
|
+
|
|
213
|
+
return {
|
|
214
|
+
type,
|
|
215
|
+
confidence,
|
|
216
|
+
score,
|
|
217
|
+
allScores: scores
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
module.exports = {
|
|
222
|
+
classifyChoreType,
|
|
223
|
+
classifyWithConfidence,
|
|
224
|
+
classifyWithDetails,
|
|
225
|
+
TYPE_KEYWORDS,
|
|
226
|
+
// Expose helpers for testing
|
|
227
|
+
normalizeInput,
|
|
228
|
+
escapeRegex,
|
|
229
|
+
calculateScores,
|
|
230
|
+
findWinningType,
|
|
231
|
+
getConfidenceLevel
|
|
232
|
+
};
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chore Type Taxonomy
|
|
3
|
+
* Defines the 4 chore types and their workflow guidance for the chore-planning and chore-mode skills.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Chore types
|
|
8
|
+
* @constant {Object}
|
|
9
|
+
*/
|
|
10
|
+
const CHORE_TYPES = Object.freeze({
|
|
11
|
+
REFACTOR: 'refactor',
|
|
12
|
+
DEPENDENCY: 'dependency',
|
|
13
|
+
CLEANUP: 'cleanup',
|
|
14
|
+
TOOLING: 'tooling'
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Valid chore type values as array
|
|
19
|
+
* @constant {Array<string>}
|
|
20
|
+
*/
|
|
21
|
+
const VALID_CHORE_TYPES = Object.freeze(Object.values(CHORE_TYPES));
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Guidance for each chore type
|
|
25
|
+
* @constant {Object}
|
|
26
|
+
*/
|
|
27
|
+
const CHORE_TYPE_GUIDANCE = Object.freeze({
|
|
28
|
+
[CHORE_TYPES.REFACTOR]: {
|
|
29
|
+
scope: [
|
|
30
|
+
'Define clear boundaries - what code is being restructured',
|
|
31
|
+
'Identify all callers/dependents of code being changed',
|
|
32
|
+
'Ensure behavior remains unchanged (refactor, not rewrite)',
|
|
33
|
+
'Consider breaking into smaller refactors if scope is large'
|
|
34
|
+
],
|
|
35
|
+
verification: [
|
|
36
|
+
'All existing tests pass without modification',
|
|
37
|
+
'No new functionality added (that requires new tests)',
|
|
38
|
+
'Code review confirms behavior preservation',
|
|
39
|
+
'Performance is not degraded'
|
|
40
|
+
],
|
|
41
|
+
testHandling: {
|
|
42
|
+
required: true,
|
|
43
|
+
approach: 'Run all tests for affected modules before and after. Update test file paths/imports if moved. Do NOT change test assertions - if tests fail, the refactor broke behavior.'
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
[CHORE_TYPES.DEPENDENCY]: {
|
|
47
|
+
scope: [
|
|
48
|
+
'Identify which packages are being updated',
|
|
49
|
+
'Check changelogs for breaking changes',
|
|
50
|
+
'Note any deprecated APIs that need migration',
|
|
51
|
+
'Consider update strategy: one at a time vs batch'
|
|
52
|
+
],
|
|
53
|
+
verification: [
|
|
54
|
+
'All tests pass after update',
|
|
55
|
+
'Application builds successfully',
|
|
56
|
+
'No new deprecation warnings (or documented)',
|
|
57
|
+
'Security vulnerabilities addressed (if security update)'
|
|
58
|
+
],
|
|
59
|
+
testHandling: {
|
|
60
|
+
required: false,
|
|
61
|
+
approach: 'Run full test suite to catch regressions. No new tests needed unless migrating to new API patterns. Document any test changes needed due to library API changes.'
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
[CHORE_TYPES.CLEANUP]: {
|
|
65
|
+
scope: [
|
|
66
|
+
'Define what is being cleaned (dead code, unused files, etc.)',
|
|
67
|
+
'Verify code is actually unused (grep for references)',
|
|
68
|
+
'Set clear boundaries to avoid scope creep',
|
|
69
|
+
'Consider impact on git history/blame'
|
|
70
|
+
],
|
|
71
|
+
verification: [
|
|
72
|
+
'All tests still pass',
|
|
73
|
+
'No broken imports or references',
|
|
74
|
+
'Application runs correctly',
|
|
75
|
+
'Removed code was actually unused'
|
|
76
|
+
],
|
|
77
|
+
testHandling: {
|
|
78
|
+
required: false,
|
|
79
|
+
approach: 'Run existing tests to ensure nothing breaks. Remove tests only if they test deleted code. No new tests needed for cleanup work.'
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
[CHORE_TYPES.TOOLING]: {
|
|
83
|
+
scope: [
|
|
84
|
+
'Define what tooling is being changed (CI, build, dev environment)',
|
|
85
|
+
'Document current behavior before changes',
|
|
86
|
+
'Consider impact on team workflows',
|
|
87
|
+
'Plan rollback strategy if changes cause issues'
|
|
88
|
+
],
|
|
89
|
+
verification: [
|
|
90
|
+
'CI pipeline passes',
|
|
91
|
+
'Build completes successfully',
|
|
92
|
+
'Dev environment works for all team members',
|
|
93
|
+
'No regression in build times or developer experience'
|
|
94
|
+
],
|
|
95
|
+
testHandling: {
|
|
96
|
+
required: false,
|
|
97
|
+
approach: 'Verify tooling changes work via manual testing or CI runs. Add integration tests only if tooling is complex. Focus on verification over unit testing for infrastructure.'
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Normalize a chore type string (lowercase, trimmed)
|
|
104
|
+
* @param {string} type - Type to normalize
|
|
105
|
+
* @returns {string|null} Normalized type or null if input is invalid
|
|
106
|
+
*/
|
|
107
|
+
function normalizeChoreType(type) {
|
|
108
|
+
if (type === null || type === undefined) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
if (typeof type !== 'string') {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
return type.toLowerCase().trim();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Check if a chore type is valid (case-insensitive)
|
|
119
|
+
* @param {string} type - Type to validate
|
|
120
|
+
* @returns {boolean} True if type is valid
|
|
121
|
+
*/
|
|
122
|
+
function isValidChoreType(type) {
|
|
123
|
+
const normalized = normalizeChoreType(type);
|
|
124
|
+
if (normalized === null) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
return VALID_CHORE_TYPES.includes(normalized);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Get guidance for a chore type
|
|
132
|
+
* @param {string} type - Chore type (case-insensitive)
|
|
133
|
+
* @returns {Object} Guidance object with scope, verification, and testHandling
|
|
134
|
+
* @throws {Error} If type is null, undefined, or invalid
|
|
135
|
+
*/
|
|
136
|
+
function getGuidance(type) {
|
|
137
|
+
if (type === null || type === undefined) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
'Chore type is required. Valid types: refactor, dependency, cleanup, tooling'
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const normalized = normalizeChoreType(type);
|
|
144
|
+
|
|
145
|
+
if (!normalized || !VALID_CHORE_TYPES.includes(normalized)) {
|
|
146
|
+
throw new Error(
|
|
147
|
+
`Invalid chore type: "${type}". Valid types: refactor, dependency, cleanup, tooling`
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return CHORE_TYPE_GUIDANCE[normalized];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Get all chore types
|
|
156
|
+
* @returns {Array<string>} Array of valid chore types
|
|
157
|
+
*/
|
|
158
|
+
function getChoreTypes() {
|
|
159
|
+
return [...VALID_CHORE_TYPES];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
module.exports = {
|
|
163
|
+
CHORE_TYPES,
|
|
164
|
+
VALID_CHORE_TYPES,
|
|
165
|
+
CHORE_TYPE_GUIDANCE,
|
|
166
|
+
normalizeChoreType,
|
|
167
|
+
isValidChoreType,
|
|
168
|
+
getGuidance,
|
|
169
|
+
getChoreTypes,
|
|
170
|
+
// Alias for step definitions
|
|
171
|
+
types: CHORE_TYPES
|
|
172
|
+
};
|
package/package.json
CHANGED
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: chore-mode
|
|
3
|
+
description: Guide implementation of standalone chores with type-appropriate guidance, verification steps, and test handling. Receives enriched context from chore-planning and executes with iteration until verification passes.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Chore Mode Skill
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
10
|
+
│ Standalone Chore Execution │
|
|
11
|
+
│ │
|
|
12
|
+
│ chore-planning → [CHORE MODE] → Done │
|
|
13
|
+
│ ▲▲▲▲▲▲▲▲▲▲▲ │
|
|
14
|
+
│ YOU ARE HERE │
|
|
15
|
+
│ │
|
|
16
|
+
│ Chores are focused tasks - no speed/stable/production progression. │
|
|
17
|
+
│ Execute once with type-appropriate verification, then done. │
|
|
18
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Guides Claude Code through chore execution with type-specific guidance, test handling, and verification criteria from the chore taxonomy.
|
|
22
|
+
|
|
23
|
+
## Instructions
|
|
24
|
+
|
|
25
|
+
When this skill is activated, you are executing a standalone chore. The chore-planning skill has already classified the type and built enriched context. Follow this structured approach:
|
|
26
|
+
|
|
27
|
+
### Overview
|
|
28
|
+
|
|
29
|
+
**Chore Mode Goal:** Execute the chore according to type-specific guidance and verify completion using taxonomy criteria.
|
|
30
|
+
|
|
31
|
+
**Key Principles:**
|
|
32
|
+
- **Type-aware execution** - Different chore types have different test handling and verification
|
|
33
|
+
- **Guided verification** - Use taxonomy verification checklist, not arbitrary checks
|
|
34
|
+
- **Iteration with limits** - Max 5 iterations to achieve verification
|
|
35
|
+
- **No mode progression** - Chores don't have speed/stable/production phases
|
|
36
|
+
|
|
37
|
+
**Chore Types Quick Reference:**
|
|
38
|
+
|
|
39
|
+
| Type | Test Handling | Key Constraint |
|
|
40
|
+
|------|---------------|----------------|
|
|
41
|
+
| refactor | Affected tests only | Do NOT modify test assertions |
|
|
42
|
+
| dependency | Full test suite | Check for deprecation warnings |
|
|
43
|
+
| cleanup | Affected tests | Verify code is actually unused |
|
|
44
|
+
| tooling | CI/manual verification | Focus on verification over unit tests |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Implementation Steps
|
|
49
|
+
|
|
50
|
+
### Step 1: Receive and Display Context
|
|
51
|
+
|
|
52
|
+
**Your task:** Acknowledge the context passed from chore-planning.
|
|
53
|
+
|
|
54
|
+
You will receive:
|
|
55
|
+
- `choreContext.chore` - Chore ID, title, description
|
|
56
|
+
- `choreContext.classification` - Type and confidence
|
|
57
|
+
- `choreContext.guidance` - Scope, verification, testHandling from taxonomy
|
|
58
|
+
- `choreContext.implementationPlan` - Files to modify, affected tests
|
|
59
|
+
|
|
60
|
+
**Display:**
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
64
|
+
🔧 Chore Mode: [Chore Title]
|
|
65
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
66
|
+
|
|
67
|
+
Type: [TYPE] (confidence: [high/medium/low])
|
|
68
|
+
Chore ID: #[id]
|
|
69
|
+
|
|
70
|
+
Implementation Plan:
|
|
71
|
+
• Files to modify: [list from context]
|
|
72
|
+
• Affected tests: [list from context]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Move to Step 2 automatically.**
|
|
76
|
+
|
|
77
|
+
### Step 2: Create Worktree
|
|
78
|
+
|
|
79
|
+
**Your task:** Create an isolated worktree for this chore.
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
jettypod work start [chore-id]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This creates a worktree at `.jettypod-work/[id]-[title-slug]` and switches to a new branch.
|
|
86
|
+
|
|
87
|
+
**Display:**
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
📁 Worktree created: .jettypod-work/[id]-[title-slug]
|
|
91
|
+
Branch: chore-[id]-[title-slug]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Move to Step 3 automatically.**
|
|
95
|
+
|
|
96
|
+
### Step 3: Establish Test Baseline
|
|
97
|
+
|
|
98
|
+
**Your task:** Run tests to establish baseline before making changes.
|
|
99
|
+
|
|
100
|
+
**Test handling varies by type:**
|
|
101
|
+
|
|
102
|
+
**For REFACTOR:**
|
|
103
|
+
```bash
|
|
104
|
+
# Run only affected module tests
|
|
105
|
+
npm test -- [affected-test-patterns]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**For DEPENDENCY:**
|
|
109
|
+
```bash
|
|
110
|
+
# Run full test suite
|
|
111
|
+
npm test
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**For CLEANUP:**
|
|
115
|
+
```bash
|
|
116
|
+
# Run affected tests
|
|
117
|
+
npm test -- [affected-test-patterns]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**For TOOLING:**
|
|
121
|
+
```bash
|
|
122
|
+
# Run CI pipeline or specific verification
|
|
123
|
+
# (may not have unit tests)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Display:**
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
🧪 Establishing test baseline...
|
|
130
|
+
|
|
131
|
+
Baseline Result:
|
|
132
|
+
Tests: [X] passing / [Y] total
|
|
133
|
+
Execution time: [Z]s
|
|
134
|
+
|
|
135
|
+
✅ Baseline established - all tests passing
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**CRITICAL:** If baseline tests fail, STOP. Fix existing failures before proceeding with chore work.
|
|
139
|
+
|
|
140
|
+
**Move to Step 4 automatically.**
|
|
141
|
+
|
|
142
|
+
### Step 4: Display Type-Specific Guidance
|
|
143
|
+
|
|
144
|
+
**Your task:** Display warnings and constraints based on chore type.
|
|
145
|
+
|
|
146
|
+
**Load guidance from taxonomy:**
|
|
147
|
+
|
|
148
|
+
```javascript
|
|
149
|
+
const { getGuidance } = require('./lib/chore-taxonomy');
|
|
150
|
+
const guidance = getGuidance('[chore-type]');
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Display type-specific warnings:**
|
|
154
|
+
|
|
155
|
+
**For REFACTOR:**
|
|
156
|
+
```
|
|
157
|
+
⚠️ REFACTOR CONSTRAINTS:
|
|
158
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
159
|
+
• All existing tests MUST pass WITHOUT modification
|
|
160
|
+
• If tests fail, the refactor broke behavior - FIX THE CODE, not the tests
|
|
161
|
+
• No new functionality - this is restructuring only
|
|
162
|
+
• Behavior must be preserved exactly
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**For DEPENDENCY:**
|
|
166
|
+
```
|
|
167
|
+
⚠️ DEPENDENCY CONSTRAINTS:
|
|
168
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
169
|
+
• Run FULL test suite to catch regressions
|
|
170
|
+
• Check for deprecation warnings after update
|
|
171
|
+
• Review changelog for breaking changes
|
|
172
|
+
• Update code if API changed
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**For CLEANUP:**
|
|
176
|
+
```
|
|
177
|
+
⚠️ CLEANUP CONSTRAINTS:
|
|
178
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
179
|
+
• VERIFY code is actually unused before deleting
|
|
180
|
+
• Search for all references (grep for function names)
|
|
181
|
+
• Remove tests ONLY if they test deleted code
|
|
182
|
+
• Check for dynamic references (string-based imports)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**For TOOLING:**
|
|
186
|
+
```
|
|
187
|
+
⚠️ TOOLING CONSTRAINTS:
|
|
188
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
189
|
+
• Verify via CI run or manual testing
|
|
190
|
+
• Focus on verification over unit testing
|
|
191
|
+
• Document current behavior before changes
|
|
192
|
+
• Plan rollback strategy
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Move to Step 5 automatically.**
|
|
196
|
+
|
|
197
|
+
### Step 5: Execute with Iteration
|
|
198
|
+
|
|
199
|
+
**Your task:** Make changes and iterate until tests pass. Max 5 iterations.
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
━━━ Iteration [N]/5 ━━━
|
|
203
|
+
|
|
204
|
+
✍️ Making changes...
|
|
205
|
+
[Describe what you're changing]
|
|
206
|
+
|
|
207
|
+
🧪 Running tests...
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**On each iteration:**
|
|
211
|
+
1. Make focused changes based on implementation plan
|
|
212
|
+
2. Run appropriate tests (type-dependent)
|
|
213
|
+
3. Check results
|
|
214
|
+
|
|
215
|
+
**Display progress:**
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
📊 Progress: [X]/[Y] tests passing
|
|
219
|
+
|
|
220
|
+
✅ Newly passing:
|
|
221
|
+
• [test name]
|
|
222
|
+
|
|
223
|
+
❌ Still failing:
|
|
224
|
+
• [test name]: [brief error]
|
|
225
|
+
|
|
226
|
+
🔧 Next: [what you'll fix]
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Exit conditions:**
|
|
230
|
+
- ✅ All tests pass → Move to Step 6
|
|
231
|
+
- ❌ Max iterations reached → Display failure, ask user for guidance
|
|
232
|
+
|
|
233
|
+
**On max iterations:**
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
⚠️ Maximum iterations (5) reached
|
|
237
|
+
|
|
238
|
+
Final Progress: [X]/[Y] tests passing
|
|
239
|
+
|
|
240
|
+
Still failing:
|
|
241
|
+
• [test name]: [error]
|
|
242
|
+
|
|
243
|
+
Options:
|
|
244
|
+
1. Review implementation approach
|
|
245
|
+
2. Break into smaller changes
|
|
246
|
+
3. Get user guidance
|
|
247
|
+
|
|
248
|
+
What would you like to do?
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
**STOP and wait for user input if max iterations reached.**
|
|
252
|
+
|
|
253
|
+
### Step 6: Run Verification Checklist
|
|
254
|
+
|
|
255
|
+
**Your task:** Run through type-specific verification criteria from taxonomy.
|
|
256
|
+
|
|
257
|
+
**Load verification from taxonomy:**
|
|
258
|
+
|
|
259
|
+
```javascript
|
|
260
|
+
const { getGuidance } = require('./lib/chore-taxonomy');
|
|
261
|
+
const guidance = getGuidance('[chore-type]');
|
|
262
|
+
// guidance.verification contains the checklist
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**Display and verify each item:**
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
269
|
+
🔍 Verification Checklist
|
|
270
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
271
|
+
|
|
272
|
+
[✅/❌] All existing tests pass without modification
|
|
273
|
+
[✅/❌] No new functionality added
|
|
274
|
+
[✅/❌] Code review confirms behavior preservation
|
|
275
|
+
[✅/❌] Performance is not degraded
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Verification methods:**
|
|
279
|
+
- **Tests pass**: Run `npm test` and check exit code
|
|
280
|
+
- **No new functionality**: Review diff for new features
|
|
281
|
+
- **Behavior preservation**: Compare before/after behavior
|
|
282
|
+
- **Performance**: Run benchmarks if applicable
|
|
283
|
+
|
|
284
|
+
**If any verification fails:**
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
❌ Verification failed:
|
|
288
|
+
• [failed item]: [reason]
|
|
289
|
+
|
|
290
|
+
Returning to iteration loop...
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Go back to Step 5 to fix issues.
|
|
294
|
+
|
|
295
|
+
**If all verification passes → Move to Step 7.**
|
|
296
|
+
|
|
297
|
+
### Step 7: Complete and Merge
|
|
298
|
+
|
|
299
|
+
**Your task:** Commit changes and merge to main.
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
# Stage and commit
|
|
303
|
+
git add .
|
|
304
|
+
git commit -m "chore: [brief description]"
|
|
305
|
+
git push
|
|
306
|
+
|
|
307
|
+
# Merge to main (auto-marks chore done)
|
|
308
|
+
jettypod work merge
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**Display:**
|
|
312
|
+
|
|
313
|
+
```
|
|
314
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
315
|
+
✅ Chore Complete
|
|
316
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
317
|
+
|
|
318
|
+
Type: [TYPE]
|
|
319
|
+
Iterations: [N]/5
|
|
320
|
+
Tests: [X]/[Y] passing
|
|
321
|
+
|
|
322
|
+
Verification:
|
|
323
|
+
✅ All existing tests pass without modification
|
|
324
|
+
✅ No new functionality added
|
|
325
|
+
✅ Code review confirms behavior preservation
|
|
326
|
+
✅ Performance is not degraded
|
|
327
|
+
|
|
328
|
+
Merged to main. Chore #[id] marked done.
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**End skill.**
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Error Handling
|
|
336
|
+
|
|
337
|
+
### Baseline Tests Fail
|
|
338
|
+
```
|
|
339
|
+
❌ Cannot proceed - baseline tests failing
|
|
340
|
+
|
|
341
|
+
[X] tests failing before chore work started.
|
|
342
|
+
Fix existing test failures before proceeding.
|
|
343
|
+
|
|
344
|
+
Failing tests:
|
|
345
|
+
• [test name]: [error]
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Verification Loop
|
|
349
|
+
If verification fails repeatedly (3+ times on same item):
|
|
350
|
+
```
|
|
351
|
+
⚠️ Verification stuck on: [item]
|
|
352
|
+
|
|
353
|
+
This has failed [N] times. Options:
|
|
354
|
+
1. Review the implementation approach
|
|
355
|
+
2. Check if this verification is applicable
|
|
356
|
+
3. Ask user for guidance
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Worktree Issues
|
|
360
|
+
```
|
|
361
|
+
❌ Worktree creation failed
|
|
362
|
+
|
|
363
|
+
Error: [message]
|
|
364
|
+
|
|
365
|
+
Try:
|
|
366
|
+
jettypod work cleanup
|
|
367
|
+
jettypod work start [chore-id]
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Type Reference
|
|
373
|
+
|
|
374
|
+
### REFACTOR
|
|
375
|
+
- **Goal:** Restructure code without changing behavior
|
|
376
|
+
- **Tests:** Affected modules only
|
|
377
|
+
- **Key rule:** NEVER modify test assertions
|
|
378
|
+
- **Verification:** Tests pass, behavior unchanged
|
|
379
|
+
|
|
380
|
+
### DEPENDENCY
|
|
381
|
+
- **Goal:** Update packages safely
|
|
382
|
+
- **Tests:** Full suite
|
|
383
|
+
- **Key rule:** Check changelogs for breaking changes
|
|
384
|
+
- **Verification:** Tests pass, no deprecation warnings
|
|
385
|
+
|
|
386
|
+
### CLEANUP
|
|
387
|
+
- **Goal:** Remove unused code
|
|
388
|
+
- **Tests:** Affected modules
|
|
389
|
+
- **Key rule:** Verify code is actually unused
|
|
390
|
+
- **Verification:** No broken references, tests pass
|
|
391
|
+
|
|
392
|
+
### TOOLING
|
|
393
|
+
- **Goal:** Improve build/CI/dev tools
|
|
394
|
+
- **Tests:** CI pipeline or manual
|
|
395
|
+
- **Key rule:** Plan rollback strategy
|
|
396
|
+
- **Verification:** CI passes, workflows work
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-specific verification runner for chore-mode skill
|
|
3
|
+
* Runs verification checklist from chore taxonomy based on chore type
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { getGuidance, CHORE_TYPES } = require('../../../lib/chore-taxonomy');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Create a verification check result
|
|
10
|
+
*
|
|
11
|
+
* @param {string} description - What is being verified
|
|
12
|
+
* @param {boolean} passed - Whether the check passed
|
|
13
|
+
* @param {string} [details] - Additional details or failure reason
|
|
14
|
+
* @returns {{description: string, passed: boolean, details?: string}}
|
|
15
|
+
*/
|
|
16
|
+
function createCheck(description, passed, details = null) {
|
|
17
|
+
const check = { description, passed };
|
|
18
|
+
if (details) check.details = details;
|
|
19
|
+
return check;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Run all verification checks for a chore type
|
|
24
|
+
*
|
|
25
|
+
* @param {string} type - Chore type (refactor, dependency, cleanup, tooling)
|
|
26
|
+
* @param {object} context - Context about the chore execution
|
|
27
|
+
* @param {object} context.testResult - Test execution result
|
|
28
|
+
* @param {boolean} context.testResult.passed - Whether tests passed
|
|
29
|
+
* @param {number} context.testResult.total - Total tests run
|
|
30
|
+
* @param {boolean} [context.testsModified] - Whether test assertions were changed
|
|
31
|
+
* @param {boolean} [context.newFunctionalityAdded] - Whether new features were added
|
|
32
|
+
* @param {string[]} [context.deprecationWarnings] - Any deprecation warnings found
|
|
33
|
+
* @param {boolean} [context.unusedCodeVerified] - Whether code was verified unused
|
|
34
|
+
* @param {boolean} [context.ciPassed] - Whether CI pipeline passed
|
|
35
|
+
* @returns {{passed: boolean, checks: Array<{description: string, passed: boolean, details?: string}>}}
|
|
36
|
+
*/
|
|
37
|
+
function runVerificationChecklist(type, context = {}) {
|
|
38
|
+
const guidance = getGuidance(type);
|
|
39
|
+
const checks = [];
|
|
40
|
+
let allPassed = true;
|
|
41
|
+
|
|
42
|
+
// Run type-specific verification based on taxonomy criteria
|
|
43
|
+
switch (type) {
|
|
44
|
+
case CHORE_TYPES.REFACTOR:
|
|
45
|
+
checks.push(...runRefactorChecks(guidance, context));
|
|
46
|
+
break;
|
|
47
|
+
|
|
48
|
+
case CHORE_TYPES.DEPENDENCY:
|
|
49
|
+
checks.push(...runDependencyChecks(guidance, context));
|
|
50
|
+
break;
|
|
51
|
+
|
|
52
|
+
case CHORE_TYPES.CLEANUP:
|
|
53
|
+
checks.push(...runCleanupChecks(guidance, context));
|
|
54
|
+
break;
|
|
55
|
+
|
|
56
|
+
case CHORE_TYPES.TOOLING:
|
|
57
|
+
checks.push(...runToolingChecks(guidance, context));
|
|
58
|
+
break;
|
|
59
|
+
|
|
60
|
+
default:
|
|
61
|
+
checks.push(createCheck(
|
|
62
|
+
'Valid chore type',
|
|
63
|
+
false,
|
|
64
|
+
`Unknown type: ${type}`
|
|
65
|
+
));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Calculate overall pass/fail
|
|
69
|
+
allPassed = checks.every(check => check.passed);
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
passed: allPassed,
|
|
73
|
+
checks
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Run refactor-specific verification checks
|
|
79
|
+
*/
|
|
80
|
+
function runRefactorChecks(guidance, context) {
|
|
81
|
+
const checks = [];
|
|
82
|
+
|
|
83
|
+
// "All existing tests pass without modification"
|
|
84
|
+
checks.push(createCheck(
|
|
85
|
+
'All existing tests pass without modification',
|
|
86
|
+
context.testResult?.passed === true,
|
|
87
|
+
context.testResult?.passed ? null : 'Tests failed - refactor may have broken behavior'
|
|
88
|
+
));
|
|
89
|
+
|
|
90
|
+
// Check if tests were modified (should NOT be)
|
|
91
|
+
checks.push(createCheck(
|
|
92
|
+
'No test assertions modified',
|
|
93
|
+
context.testsModified !== true,
|
|
94
|
+
context.testsModified ? 'Test assertions were changed - this violates refactor rules' : null
|
|
95
|
+
));
|
|
96
|
+
|
|
97
|
+
// "No new functionality added"
|
|
98
|
+
checks.push(createCheck(
|
|
99
|
+
'No new functionality added',
|
|
100
|
+
context.newFunctionalityAdded !== true,
|
|
101
|
+
context.newFunctionalityAdded ? 'New functionality detected - this should be a feature, not a refactor' : null
|
|
102
|
+
));
|
|
103
|
+
|
|
104
|
+
// "Performance is not degraded" - assumed pass unless context indicates otherwise
|
|
105
|
+
checks.push(createCheck(
|
|
106
|
+
'Performance not degraded',
|
|
107
|
+
context.performanceDegraded !== true,
|
|
108
|
+
context.performanceDegraded ? 'Performance regression detected' : null
|
|
109
|
+
));
|
|
110
|
+
|
|
111
|
+
return checks;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Run dependency-specific verification checks
|
|
116
|
+
*/
|
|
117
|
+
function runDependencyChecks(guidance, context) {
|
|
118
|
+
const checks = [];
|
|
119
|
+
|
|
120
|
+
// "All tests pass after update"
|
|
121
|
+
checks.push(createCheck(
|
|
122
|
+
'All tests pass after update',
|
|
123
|
+
context.testResult?.passed === true,
|
|
124
|
+
context.testResult?.passed ? null : 'Tests failed after dependency update'
|
|
125
|
+
));
|
|
126
|
+
|
|
127
|
+
// "Application builds successfully" - assumed from test pass
|
|
128
|
+
checks.push(createCheck(
|
|
129
|
+
'Application builds successfully',
|
|
130
|
+
context.buildPassed !== false,
|
|
131
|
+
context.buildPassed === false ? 'Build failed' : null
|
|
132
|
+
));
|
|
133
|
+
|
|
134
|
+
// "No new deprecation warnings"
|
|
135
|
+
const hasDeprecations = context.deprecationWarnings && context.deprecationWarnings.length > 0;
|
|
136
|
+
checks.push(createCheck(
|
|
137
|
+
'No new deprecation warnings (or documented)',
|
|
138
|
+
!hasDeprecations || context.deprecationsDocumented === true,
|
|
139
|
+
hasDeprecations && !context.deprecationsDocumented
|
|
140
|
+
? `Found ${context.deprecationWarnings.length} deprecation warnings`
|
|
141
|
+
: null
|
|
142
|
+
));
|
|
143
|
+
|
|
144
|
+
return checks;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Run cleanup-specific verification checks
|
|
149
|
+
*/
|
|
150
|
+
function runCleanupChecks(guidance, context) {
|
|
151
|
+
const checks = [];
|
|
152
|
+
|
|
153
|
+
// "All tests still pass"
|
|
154
|
+
checks.push(createCheck(
|
|
155
|
+
'All tests still pass',
|
|
156
|
+
context.testResult?.passed === true,
|
|
157
|
+
context.testResult?.passed ? null : 'Tests failed after cleanup'
|
|
158
|
+
));
|
|
159
|
+
|
|
160
|
+
// "No broken imports or references"
|
|
161
|
+
checks.push(createCheck(
|
|
162
|
+
'No broken imports or references',
|
|
163
|
+
context.brokenReferences !== true,
|
|
164
|
+
context.brokenReferences ? 'Broken references found' : null
|
|
165
|
+
));
|
|
166
|
+
|
|
167
|
+
// "Removed code was actually unused"
|
|
168
|
+
checks.push(createCheck(
|
|
169
|
+
'Removed code was verified unused',
|
|
170
|
+
context.unusedCodeVerified === true,
|
|
171
|
+
context.unusedCodeVerified ? null : 'Code usage was not verified before removal'
|
|
172
|
+
));
|
|
173
|
+
|
|
174
|
+
return checks;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Run tooling-specific verification checks
|
|
179
|
+
*/
|
|
180
|
+
function runToolingChecks(guidance, context) {
|
|
181
|
+
const checks = [];
|
|
182
|
+
|
|
183
|
+
// "CI pipeline passes"
|
|
184
|
+
checks.push(createCheck(
|
|
185
|
+
'CI pipeline passes',
|
|
186
|
+
context.ciPassed === true,
|
|
187
|
+
context.ciPassed ? null : 'CI not verified or failed'
|
|
188
|
+
));
|
|
189
|
+
|
|
190
|
+
// "Build completes successfully"
|
|
191
|
+
checks.push(createCheck(
|
|
192
|
+
'Build completes successfully',
|
|
193
|
+
context.buildPassed !== false,
|
|
194
|
+
context.buildPassed === false ? 'Build failed' : null
|
|
195
|
+
));
|
|
196
|
+
|
|
197
|
+
// "No regression in build times or developer experience"
|
|
198
|
+
checks.push(createCheck(
|
|
199
|
+
'No regression in build times/DX',
|
|
200
|
+
context.dxRegression !== true,
|
|
201
|
+
context.dxRegression ? 'Developer experience regression detected' : null
|
|
202
|
+
));
|
|
203
|
+
|
|
204
|
+
return checks;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Format verification results for display
|
|
209
|
+
*
|
|
210
|
+
* @param {{passed: boolean, checks: Array}} result - Verification result
|
|
211
|
+
* @returns {string} Formatted string for display
|
|
212
|
+
*/
|
|
213
|
+
function formatVerificationResult(result) {
|
|
214
|
+
const lines = [];
|
|
215
|
+
lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
216
|
+
lines.push('🔍 Verification Checklist');
|
|
217
|
+
lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
218
|
+
lines.push('');
|
|
219
|
+
|
|
220
|
+
for (const check of result.checks) {
|
|
221
|
+
const icon = check.passed ? '✅' : '❌';
|
|
222
|
+
lines.push(`${icon} ${check.description}`);
|
|
223
|
+
if (check.details) {
|
|
224
|
+
lines.push(` └─ ${check.details}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
lines.push('');
|
|
229
|
+
if (result.passed) {
|
|
230
|
+
lines.push('✅ All verification checks passed');
|
|
231
|
+
} else {
|
|
232
|
+
const failedCount = result.checks.filter(c => !c.passed).length;
|
|
233
|
+
lines.push(`❌ ${failedCount} verification check(s) failed`);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return lines.join('\n');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Get verification criteria from taxonomy for display
|
|
241
|
+
*
|
|
242
|
+
* @param {string} type - Chore type
|
|
243
|
+
* @returns {string[]} Array of verification criteria strings
|
|
244
|
+
*/
|
|
245
|
+
function getVerificationCriteria(type) {
|
|
246
|
+
const guidance = getGuidance(type);
|
|
247
|
+
return guidance.verification || [];
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
module.exports = {
|
|
251
|
+
runVerificationChecklist,
|
|
252
|
+
formatVerificationResult,
|
|
253
|
+
getVerificationCriteria,
|
|
254
|
+
createCheck
|
|
255
|
+
};
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: chore-planning
|
|
3
|
+
description: Guide standalone chore planning with automatic type classification, taxonomy guidance loading, and routing to chore-mode for execution. Use when user starts a standalone chore (chore with no parent feature), mentions planning a chore, or says "help me with this chore".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Chore Planning Skill
|
|
7
|
+
|
|
8
|
+
Guides Claude through standalone chore planning including automatic type classification, loading type-specific guidance from the taxonomy, building enriched context, and routing to chore-mode for execution.
|
|
9
|
+
|
|
10
|
+
## Instructions
|
|
11
|
+
|
|
12
|
+
When this skill is activated, you are helping plan a standalone chore (one without a parent feature). Follow this structured approach:
|
|
13
|
+
|
|
14
|
+
### Step 1: Understand the Chore Context
|
|
15
|
+
|
|
16
|
+
You'll receive context about:
|
|
17
|
+
- Chore title and description
|
|
18
|
+
- Project context
|
|
19
|
+
- No parent feature (standalone chores don't have features)
|
|
20
|
+
|
|
21
|
+
Display:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
25
|
+
🔧 Planning Standalone Chore
|
|
26
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
27
|
+
|
|
28
|
+
**Chore:** [Title]
|
|
29
|
+
**Description:** [Description if provided]
|
|
30
|
+
|
|
31
|
+
Analyzing chore type...
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Step 2: Classify Chore Type
|
|
35
|
+
|
|
36
|
+
**CRITICAL:** Use the chore-classifier to determine the chore type automatically.
|
|
37
|
+
|
|
38
|
+
**Execute this code:**
|
|
39
|
+
|
|
40
|
+
```javascript
|
|
41
|
+
const { classifyChoreType, classifyWithConfidence } = require('./lib/chore-classifier');
|
|
42
|
+
|
|
43
|
+
const choreTitle = '[chore title]';
|
|
44
|
+
const choreDescription = '[chore description or empty string]';
|
|
45
|
+
|
|
46
|
+
const classification = classifyWithConfidence(choreTitle, choreDescription);
|
|
47
|
+
console.log('Classification:', JSON.stringify(classification, null, 2));
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Display the classification result:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
**Type Classification:** [type] (confidence: [high/medium/low])
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**If confidence is low:**
|
|
57
|
+
```
|
|
58
|
+
⚠️ Low confidence classification. The chore might be:
|
|
59
|
+
- [type] - because [reason based on keywords found]
|
|
60
|
+
- [alternative type] - if [alternative interpretation]
|
|
61
|
+
|
|
62
|
+
Proceeding with [type]. Let me know if this should be different.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Step 3: Load Taxonomy Guidance
|
|
66
|
+
|
|
67
|
+
**Execute this code to load type-specific guidance:**
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
const { getGuidance } = require('./lib/chore-taxonomy');
|
|
71
|
+
|
|
72
|
+
const guidance = getGuidance('[classified-type]');
|
|
73
|
+
console.log('Guidance:', JSON.stringify(guidance, null, 2));
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Display the guidance:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
80
|
+
📋 [Type] Chore Guidance
|
|
81
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
82
|
+
|
|
83
|
+
**Scope Considerations:**
|
|
84
|
+
[List each scope item from guidance]
|
|
85
|
+
|
|
86
|
+
**Verification Criteria:**
|
|
87
|
+
[List each verification item from guidance]
|
|
88
|
+
|
|
89
|
+
**Test Handling:**
|
|
90
|
+
- Tests required: [yes/no]
|
|
91
|
+
- Approach: [testHandling.approach]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Step 4: Build Enriched Context
|
|
95
|
+
|
|
96
|
+
Combine all information into a structured context object:
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
const choreContext = {
|
|
100
|
+
chore: {
|
|
101
|
+
id: [chore-id],
|
|
102
|
+
title: '[title]',
|
|
103
|
+
description: '[description]',
|
|
104
|
+
type: 'chore',
|
|
105
|
+
parent_id: null // standalone
|
|
106
|
+
},
|
|
107
|
+
classification: {
|
|
108
|
+
type: '[classified-type]',
|
|
109
|
+
confidence: '[high/medium/low]'
|
|
110
|
+
},
|
|
111
|
+
guidance: {
|
|
112
|
+
scope: [...],
|
|
113
|
+
verification: [...],
|
|
114
|
+
testHandling: {
|
|
115
|
+
required: true/false,
|
|
116
|
+
approach: '...'
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Step 5: Analyze Codebase Impact
|
|
123
|
+
|
|
124
|
+
Based on the chore type and guidance, analyze what needs to be done:
|
|
125
|
+
|
|
126
|
+
**For REFACTOR chores:**
|
|
127
|
+
- Identify the code being restructured
|
|
128
|
+
- Find all callers/dependents
|
|
129
|
+
- List affected test files
|
|
130
|
+
|
|
131
|
+
**For DEPENDENCY chores:**
|
|
132
|
+
- Check current version
|
|
133
|
+
- Review changelog for breaking changes
|
|
134
|
+
- Identify affected code
|
|
135
|
+
|
|
136
|
+
**For CLEANUP chores:**
|
|
137
|
+
- Find all references to code being removed
|
|
138
|
+
- Verify nothing depends on it
|
|
139
|
+
- List files to modify
|
|
140
|
+
|
|
141
|
+
**For TOOLING chores:**
|
|
142
|
+
- Check current tool configuration
|
|
143
|
+
- Identify affected workflows
|
|
144
|
+
- Review CI/CD impacts
|
|
145
|
+
|
|
146
|
+
Display analysis:
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
150
|
+
🔍 Impact Analysis
|
|
151
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
152
|
+
|
|
153
|
+
**Files to modify:**
|
|
154
|
+
[List of files]
|
|
155
|
+
|
|
156
|
+
**Tests to run:**
|
|
157
|
+
[List of test files/patterns]
|
|
158
|
+
|
|
159
|
+
**Verification steps:**
|
|
160
|
+
[Specific steps based on guidance]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Step 6: Create Implementation Plan
|
|
164
|
+
|
|
165
|
+
Based on the analysis, create a focused plan:
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
169
|
+
📝 Implementation Plan
|
|
170
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
171
|
+
|
|
172
|
+
**Step 1:** [First action]
|
|
173
|
+
**Step 2:** [Second action]
|
|
174
|
+
...
|
|
175
|
+
|
|
176
|
+
**Verification:**
|
|
177
|
+
1. [First check from guidance]
|
|
178
|
+
2. [Second check from guidance]
|
|
179
|
+
...
|
|
180
|
+
|
|
181
|
+
Ready to proceed?
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Step 7: Route to Chore Mode
|
|
185
|
+
|
|
186
|
+
**WAIT for user confirmation.**
|
|
187
|
+
|
|
188
|
+
When user confirms (responds with "yes", "proceed", "let's go", etc.):
|
|
189
|
+
|
|
190
|
+
**Invoke the chore-mode skill using the Skill tool:**
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
Use the Skill tool with skill: "chore-mode"
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The chore-mode skill will:
|
|
197
|
+
1. Create a worktree for the chore
|
|
198
|
+
2. Execute the implementation plan
|
|
199
|
+
3. Run verification steps
|
|
200
|
+
4. Merge when complete
|
|
201
|
+
|
|
202
|
+
**End chore-planning skill after invoking chore-mode.**
|
|
203
|
+
|
|
204
|
+
## Key Principles
|
|
205
|
+
|
|
206
|
+
1. **Automatic classification** - AI determines chore type from title/description
|
|
207
|
+
2. **Taxonomy-driven guidance** - Load specific guidance for each chore type
|
|
208
|
+
3. **Context enrichment** - Build complete context before execution
|
|
209
|
+
4. **Impact analysis** - Understand what the chore affects
|
|
210
|
+
5. **Verification-focused** - Use type-specific verification criteria
|
|
211
|
+
6. **Seamless handoff** - Route to chore-mode with full context
|
|
212
|
+
|
|
213
|
+
## Chore Type Quick Reference
|
|
214
|
+
|
|
215
|
+
| Type | Keywords | Test Handling |
|
|
216
|
+
|------|----------|---------------|
|
|
217
|
+
| refactor | refactor, restructure, extract, rename | Run all tests, don't modify assertions |
|
|
218
|
+
| dependency | update, upgrade, bump, migrate | Run full suite, check for deprecations |
|
|
219
|
+
| cleanup | remove, delete, unused, legacy | Verify no references, run affected tests |
|
|
220
|
+
| tooling | ci, build, lint, config | Run affected pipelines |
|
|
221
|
+
|
|
222
|
+
## Validation
|
|
223
|
+
|
|
224
|
+
Before routing to chore-mode, ensure:
|
|
225
|
+
- [ ] Chore type classified
|
|
226
|
+
- [ ] Taxonomy guidance loaded
|
|
227
|
+
- [ ] Impact analysis complete
|
|
228
|
+
- [ ] Implementation plan created
|
|
229
|
+
- [ ] User confirmed ready to proceed
|
|
@@ -159,13 +159,21 @@ Once features are defined and architectural decision is made (if needed):
|
|
|
159
159
|
|
|
160
160
|
#### Step 6A: Create Features
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
**CRITICAL:** You MUST pass the `--parent=<epic-id>` flag with the actual numeric epic ID. Without this, features won't appear under the epic in the backlog tree.
|
|
163
|
+
|
|
164
|
+
Use the Bash tool to create each feature. Replace `<EPIC_ID>` with the actual epic ID number:
|
|
163
165
|
|
|
164
166
|
```javascript
|
|
165
|
-
//
|
|
166
|
-
node jettypod.js work create feature "
|
|
167
|
-
|
|
168
|
-
//
|
|
167
|
+
// CORRECT - uses actual numeric epic ID:
|
|
168
|
+
node jettypod.js work create feature "Live cursor tracking" "Track cursor positions in real-time" --parent=5
|
|
169
|
+
|
|
170
|
+
// WRONG - missing parent flag (feature won't be under epic):
|
|
171
|
+
node jettypod.js work create feature "Live cursor tracking" "Track cursor positions in real-time"
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
For each feature, execute:
|
|
175
|
+
```bash
|
|
176
|
+
node jettypod.js work create feature "<Title>" "<Description>" --parent=<EPIC_ID>
|
|
169
177
|
```
|
|
170
178
|
|
|
171
179
|
Display to user as you create each one:
|
|
@@ -331,11 +331,16 @@ node jettypod.js work implement [feature-id] \
|
|
|
331
331
|
|
|
332
332
|
**CRITICAL: NOW create the chores.** The feature has transitioned to implementation mode, so chore creation will succeed.
|
|
333
333
|
|
|
334
|
-
|
|
334
|
+
**IMPORTANT:** You MUST pass `--parent=<FEATURE_ID>` with the actual numeric feature ID. Without this, chores won't be linked to the feature.
|
|
335
|
+
|
|
336
|
+
For each chore that the user confirmed in Step 7, use the Bash tool to create it. Replace `<FEATURE_ID>` with the actual feature ID number:
|
|
335
337
|
|
|
336
338
|
```bash
|
|
337
|
-
#
|
|
338
|
-
node jettypod.js work create chore "
|
|
339
|
+
# CORRECT - uses actual numeric feature ID:
|
|
340
|
+
node jettypod.js work create chore "Implement cursor position broadcast" "Broadcast cursor positions..." --parent=12
|
|
341
|
+
|
|
342
|
+
# WRONG - missing parent flag (chore won't be linked to feature):
|
|
343
|
+
node jettypod.js work create chore "Implement cursor position broadcast" "Broadcast cursor positions..."
|
|
339
344
|
```
|
|
340
345
|
|
|
341
346
|
**Build the description from your Step 7 proposal:**
|