pmp-gywd 3.3.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.
Files changed (126) hide show
  1. package/LICENSE +27 -0
  2. package/README.md +567 -0
  3. package/bin/install.js +348 -0
  4. package/commands/gywd/add-phase.md +207 -0
  5. package/commands/gywd/anticipate.md +271 -0
  6. package/commands/gywd/bootstrap.md +336 -0
  7. package/commands/gywd/challenge.md +344 -0
  8. package/commands/gywd/check-drift.md +144 -0
  9. package/commands/gywd/complete-milestone.md +106 -0
  10. package/commands/gywd/consider-issues.md +202 -0
  11. package/commands/gywd/context.md +93 -0
  12. package/commands/gywd/create-roadmap.md +115 -0
  13. package/commands/gywd/deps.md +169 -0
  14. package/commands/gywd/digest.md +138 -0
  15. package/commands/gywd/discuss-milestone.md +47 -0
  16. package/commands/gywd/discuss-phase.md +60 -0
  17. package/commands/gywd/execute-plan.md +161 -0
  18. package/commands/gywd/extract-decisions.md +325 -0
  19. package/commands/gywd/health.md +150 -0
  20. package/commands/gywd/help.md +556 -0
  21. package/commands/gywd/history.md +278 -0
  22. package/commands/gywd/impact.md +317 -0
  23. package/commands/gywd/init.md +95 -0
  24. package/commands/gywd/insert-phase.md +227 -0
  25. package/commands/gywd/list-phase-assumptions.md +50 -0
  26. package/commands/gywd/map-codebase.md +84 -0
  27. package/commands/gywd/memory.md +159 -0
  28. package/commands/gywd/new-milestone.md +59 -0
  29. package/commands/gywd/new-project.md +315 -0
  30. package/commands/gywd/pause-work.md +123 -0
  31. package/commands/gywd/plan-fix.md +205 -0
  32. package/commands/gywd/plan-phase.md +93 -0
  33. package/commands/gywd/preview-plan.md +139 -0
  34. package/commands/gywd/profile.md +363 -0
  35. package/commands/gywd/progress.md +317 -0
  36. package/commands/gywd/remove-phase.md +338 -0
  37. package/commands/gywd/research-phase.md +91 -0
  38. package/commands/gywd/resume-work.md +40 -0
  39. package/commands/gywd/rollback.md +179 -0
  40. package/commands/gywd/status.md +42 -0
  41. package/commands/gywd/sync-github.md +234 -0
  42. package/commands/gywd/verify-work.md +71 -0
  43. package/commands/gywd/why.md +251 -0
  44. package/docs/COMMANDS.md +722 -0
  45. package/docs/CONTRIBUTING.md +342 -0
  46. package/docs/EXAMPLES.md +535 -0
  47. package/docs/GETTING-STARTED.md +262 -0
  48. package/docs/README.md +55 -0
  49. package/docs/RELEASING.md +159 -0
  50. package/get-your-work-done/core/agent-patterns.md +331 -0
  51. package/get-your-work-done/core/architecture.md +334 -0
  52. package/get-your-work-done/core/context-model-schema.json +154 -0
  53. package/get-your-work-done/core/decisions-schema.json +193 -0
  54. package/get-your-work-done/core/learning-state-schema.json +133 -0
  55. package/get-your-work-done/core/profile-schema.json +257 -0
  56. package/get-your-work-done/references/adaptive-decomposition.md +175 -0
  57. package/get-your-work-done/references/checkpoints.md +287 -0
  58. package/get-your-work-done/references/confidence-scoring.md +169 -0
  59. package/get-your-work-done/references/continuation-format.md +255 -0
  60. package/get-your-work-done/references/git-integration.md +254 -0
  61. package/get-your-work-done/references/plan-format.md +428 -0
  62. package/get-your-work-done/references/principles.md +157 -0
  63. package/get-your-work-done/references/questioning.md +162 -0
  64. package/get-your-work-done/references/research-pitfalls.md +215 -0
  65. package/get-your-work-done/references/scope-estimation.md +172 -0
  66. package/get-your-work-done/references/tdd.md +263 -0
  67. package/get-your-work-done/templates/codebase/architecture.md +255 -0
  68. package/get-your-work-done/templates/codebase/concerns.md +310 -0
  69. package/get-your-work-done/templates/codebase/conventions.md +307 -0
  70. package/get-your-work-done/templates/codebase/integrations.md +280 -0
  71. package/get-your-work-done/templates/codebase/stack.md +186 -0
  72. package/get-your-work-done/templates/codebase/structure.md +285 -0
  73. package/get-your-work-done/templates/codebase/testing.md +480 -0
  74. package/get-your-work-done/templates/config.json +18 -0
  75. package/get-your-work-done/templates/context.md +161 -0
  76. package/get-your-work-done/templates/continue-here.md +78 -0
  77. package/get-your-work-done/templates/discovery.md +146 -0
  78. package/get-your-work-done/templates/issues.md +32 -0
  79. package/get-your-work-done/templates/milestone-archive.md +123 -0
  80. package/get-your-work-done/templates/milestone-context.md +93 -0
  81. package/get-your-work-done/templates/milestone.md +115 -0
  82. package/get-your-work-done/templates/phase-prompt.md +303 -0
  83. package/get-your-work-done/templates/project.md +184 -0
  84. package/get-your-work-done/templates/research.md +529 -0
  85. package/get-your-work-done/templates/roadmap.md +196 -0
  86. package/get-your-work-done/templates/state.md +210 -0
  87. package/get-your-work-done/templates/summary.md +273 -0
  88. package/get-your-work-done/templates/uat-issues.md +143 -0
  89. package/get-your-work-done/workflows/complete-milestone.md +643 -0
  90. package/get-your-work-done/workflows/create-milestone.md +416 -0
  91. package/get-your-work-done/workflows/create-roadmap.md +481 -0
  92. package/get-your-work-done/workflows/discovery-phase.md +293 -0
  93. package/get-your-work-done/workflows/discuss-milestone.md +236 -0
  94. package/get-your-work-done/workflows/discuss-phase.md +247 -0
  95. package/get-your-work-done/workflows/execute-phase.md +1625 -0
  96. package/get-your-work-done/workflows/list-phase-assumptions.md +178 -0
  97. package/get-your-work-done/workflows/map-codebase.md +434 -0
  98. package/get-your-work-done/workflows/plan-phase.md +488 -0
  99. package/get-your-work-done/workflows/research-phase.md +436 -0
  100. package/get-your-work-done/workflows/resume-project.md +287 -0
  101. package/get-your-work-done/workflows/transition.md +580 -0
  102. package/get-your-work-done/workflows/verify-work.md +202 -0
  103. package/lib/automation/dependency-analyzer.js +635 -0
  104. package/lib/automation/doc-generator.js +643 -0
  105. package/lib/automation/index.js +42 -0
  106. package/lib/automation/test-generator.js +628 -0
  107. package/lib/context/context-analyzer.js +554 -0
  108. package/lib/context/context-cache.js +426 -0
  109. package/lib/context/context-predictor.js +622 -0
  110. package/lib/context/index.js +44 -0
  111. package/lib/memory/confidence-calibrator.js +484 -0
  112. package/lib/memory/feedback-collector.js +551 -0
  113. package/lib/memory/global-memory.js +465 -0
  114. package/lib/memory/index.js +75 -0
  115. package/lib/memory/pattern-aggregator.js +487 -0
  116. package/lib/memory/team-sync.js +501 -0
  117. package/lib/profile/index.js +24 -0
  118. package/lib/profile/pattern-learner.js +303 -0
  119. package/lib/profile/profile-manager.js +445 -0
  120. package/lib/questioning/index.js +49 -0
  121. package/lib/questioning/question-engine.js +311 -0
  122. package/lib/questioning/question-templates.js +315 -0
  123. package/lib/validators/command-validator.js +188 -0
  124. package/lib/validators/index.js +29 -0
  125. package/lib/validators/schema-validator.js +183 -0
  126. package/package.json +61 -0
@@ -0,0 +1,311 @@
1
+ /**
2
+ * Adaptive Questioning Engine
3
+ *
4
+ * Generates context-aware questions that learn from responses.
5
+ * Core component of the "sophisticated brain" for v3.0.
6
+ */
7
+
8
+ /**
9
+ * Question types for different purposes
10
+ */
11
+ const QUESTION_TYPES = {
12
+ CLARIFYING: 'clarifying', // Clarify ambiguous requirements
13
+ EXPLORATORY: 'exploratory', // Discover unknown aspects
14
+ VALIDATING: 'validating', // Confirm assumptions
15
+ TECHNICAL: 'technical', // Technical decisions
16
+ PREFERENCE: 'preference', // User preferences
17
+ CONSTRAINT: 'constraint', // Identify constraints
18
+ };
19
+
20
+ /**
21
+ * Question priority levels
22
+ */
23
+ const PRIORITY = {
24
+ CRITICAL: 'critical', // Must ask before proceeding
25
+ HIGH: 'high', // Important but can infer
26
+ MEDIUM: 'medium', // Good to know
27
+ LOW: 'low', // Nice to have
28
+ };
29
+
30
+ /**
31
+ * Question template structure
32
+ */
33
+ const createQuestion = (opts) => ({
34
+ // Spread opts first to include any extra fields (expertText, beginnerText, etc.)
35
+ ...opts,
36
+ // Then set defaults for standard fields
37
+ id: opts.id || `q-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
38
+ type: opts.type || QUESTION_TYPES.CLARIFYING,
39
+ priority: opts.priority || PRIORITY.MEDIUM,
40
+ text: opts.text,
41
+ context: opts.context || null,
42
+ options: opts.options || null,
43
+ defaultAnswer: opts.defaultAnswer || null,
44
+ followUps: opts.followUps || [],
45
+ tags: opts.tags || [],
46
+ askCondition: opts.askCondition || null,
47
+ skipIfKnown: opts.skipIfKnown || [],
48
+ });
49
+
50
+ /**
51
+ * Adaptive Questioning Engine class
52
+ */
53
+ class QuestionEngine {
54
+ constructor() {
55
+ this.questionHistory = [];
56
+ this.knowledgeBase = new Map();
57
+ this.askedQuestions = new Set();
58
+ this.userProfile = null;
59
+ }
60
+
61
+ /**
62
+ * Set user profile for personalized questions
63
+ * @param {object} profile - User profile from ProfileManager
64
+ */
65
+ setProfile(profile) {
66
+ this.userProfile = profile;
67
+ }
68
+
69
+ /**
70
+ * Record an answer to a question
71
+ * @param {string} questionId - Question ID
72
+ * @param {any} answer - The answer provided
73
+ * @param {object} metadata - Additional metadata
74
+ */
75
+ recordAnswer(questionId, answer, metadata = {}) {
76
+ this.questionHistory.push({
77
+ questionId,
78
+ answer,
79
+ timestamp: Date.now(),
80
+ ...metadata,
81
+ });
82
+
83
+ // Update knowledge base
84
+ if (metadata.knowledgeKey) {
85
+ this.knowledgeBase.set(metadata.knowledgeKey, {
86
+ value: answer,
87
+ source: 'direct-answer',
88
+ confidence: 1.0,
89
+ timestamp: Date.now(),
90
+ });
91
+ }
92
+
93
+ this.askedQuestions.add(questionId);
94
+ }
95
+
96
+ /**
97
+ * Record inferred knowledge
98
+ * @param {string} key - Knowledge key
99
+ * @param {any} value - Inferred value
100
+ * @param {number} confidence - Confidence level (0-1)
101
+ */
102
+ recordInference(key, value, confidence = 0.7) {
103
+ this.knowledgeBase.set(key, {
104
+ value,
105
+ source: 'inference',
106
+ confidence,
107
+ timestamp: Date.now(),
108
+ });
109
+ }
110
+
111
+ /**
112
+ * Check if we already know something
113
+ * @param {string} key - Knowledge key
114
+ * @param {number} minConfidence - Minimum confidence required
115
+ * @returns {boolean}
116
+ */
117
+ isKnown(key, minConfidence = 0.7) {
118
+ const knowledge = this.knowledgeBase.get(key);
119
+ if (!knowledge) return false;
120
+ return knowledge.confidence >= minConfidence;
121
+ }
122
+
123
+ /**
124
+ * Get known value
125
+ * @param {string} key - Knowledge key
126
+ * @returns {any} The known value or undefined
127
+ */
128
+ getKnowledge(key) {
129
+ const knowledge = this.knowledgeBase.get(key);
130
+ return knowledge ? knowledge.value : undefined;
131
+ }
132
+
133
+ /**
134
+ * Check if a question should be asked
135
+ * @param {object} question - Question object
136
+ * @returns {boolean}
137
+ */
138
+ shouldAsk(question) {
139
+ // Already asked this specific question
140
+ if (this.askedQuestions.has(question.id)) {
141
+ return false;
142
+ }
143
+
144
+ // Check skipIfKnown conditions
145
+ if (question.skipIfKnown && question.skipIfKnown.length > 0) {
146
+ const allKnown = question.skipIfKnown.every(key => this.isKnown(key));
147
+ if (allKnown) {
148
+ return false;
149
+ }
150
+ }
151
+
152
+ // Check custom ask condition
153
+ if (question.askCondition && typeof question.askCondition === 'function') {
154
+ return question.askCondition(this.knowledgeBase, this.userProfile);
155
+ }
156
+
157
+ return true;
158
+ }
159
+
160
+ /**
161
+ * Filter questions to only those that should be asked
162
+ * @param {Array} questions - Array of questions
163
+ * @returns {Array} Filtered questions
164
+ */
165
+ filterQuestions(questions) {
166
+ return questions.filter(q => this.shouldAsk(q));
167
+ }
168
+
169
+ /**
170
+ * Sort questions by priority
171
+ * @param {Array} questions - Array of questions
172
+ * @returns {Array} Sorted questions
173
+ */
174
+ sortByPriority(questions) {
175
+ const priorityOrder = {
176
+ [PRIORITY.CRITICAL]: 0,
177
+ [PRIORITY.HIGH]: 1,
178
+ [PRIORITY.MEDIUM]: 2,
179
+ [PRIORITY.LOW]: 3,
180
+ };
181
+
182
+ return [...questions].sort((a, b) => {
183
+ // Use ?? instead of || because 0 is a valid priority value
184
+ const aOrder = priorityOrder[a.priority] ?? 2;
185
+ const bOrder = priorityOrder[b.priority] ?? 2;
186
+ return aOrder - bOrder;
187
+ });
188
+ }
189
+
190
+ /**
191
+ * Get next questions to ask
192
+ * @param {Array} questions - Available questions
193
+ * @param {number} maxCount - Maximum number to return
194
+ * @returns {Array} Questions to ask
195
+ */
196
+ getNextQuestions(questions, maxCount = 3) {
197
+ const filtered = this.filterQuestions(questions);
198
+ const sorted = this.sortByPriority(filtered);
199
+ return sorted.slice(0, maxCount);
200
+ }
201
+
202
+ /**
203
+ * Adapt question depth based on user expertise
204
+ * @param {object} question - Question object
205
+ * @param {string} domain - Domain area
206
+ * @returns {object} Adapted question
207
+ */
208
+ adaptToExpertise(question, domain) {
209
+ if (!this.userProfile) return question;
210
+
211
+ const expertise = this.userProfile.domain?.expertiseAreas || [];
212
+ const isExpert = expertise.includes(domain);
213
+
214
+ if (isExpert) {
215
+ // Experts get more technical, less explanation
216
+ return {
217
+ ...question,
218
+ text: question.expertText || question.text,
219
+ options: question.expertOptions || question.options,
220
+ };
221
+ }
222
+
223
+ // Non-experts get more context
224
+ return {
225
+ ...question,
226
+ text: question.beginnerText || question.text,
227
+ context: question.beginnerContext || question.context,
228
+ };
229
+ }
230
+
231
+ /**
232
+ * Generate follow-up questions based on answer
233
+ * @param {object} question - Original question
234
+ * @param {any} answer - The answer provided
235
+ * @returns {Array} Follow-up questions
236
+ */
237
+ generateFollowUps(question, answer) {
238
+ if (!question.followUps || question.followUps.length === 0) {
239
+ return [];
240
+ }
241
+
242
+ return question.followUps
243
+ .filter(fu => {
244
+ if (fu.condition && typeof fu.condition === 'function') {
245
+ return fu.condition(answer);
246
+ }
247
+ if (fu.triggerAnswer !== undefined) {
248
+ return fu.triggerAnswer === answer;
249
+ }
250
+ return true;
251
+ })
252
+ .map(fu => createQuestion(fu));
253
+ }
254
+
255
+ /**
256
+ * Get question history summary
257
+ * @returns {object} Summary of asked questions
258
+ */
259
+ getHistorySummary() {
260
+ const byType = {};
261
+ const byPriority = {};
262
+
263
+ for (const entry of this.questionHistory) {
264
+ const q = entry;
265
+ byType[q.type] = (byType[q.type] || 0) + 1;
266
+ byPriority[q.priority] = (byPriority[q.priority] || 0) + 1;
267
+ }
268
+
269
+ return {
270
+ totalAsked: this.questionHistory.length,
271
+ byType,
272
+ byPriority,
273
+ knowledgeCount: this.knowledgeBase.size,
274
+ };
275
+ }
276
+
277
+ /**
278
+ * Clear all state (for testing)
279
+ */
280
+ clear() {
281
+ this.questionHistory = [];
282
+ this.knowledgeBase.clear();
283
+ this.askedQuestions.clear();
284
+ this.userProfile = null;
285
+ }
286
+
287
+ /**
288
+ * Export current knowledge base
289
+ * @returns {object} Knowledge base as plain object
290
+ */
291
+ exportKnowledge() {
292
+ return Object.fromEntries(this.knowledgeBase);
293
+ }
294
+
295
+ /**
296
+ * Import knowledge base
297
+ * @param {object} knowledge - Knowledge to import
298
+ */
299
+ importKnowledge(knowledge) {
300
+ for (const [key, value] of Object.entries(knowledge)) {
301
+ this.knowledgeBase.set(key, value);
302
+ }
303
+ }
304
+ }
305
+
306
+ module.exports = {
307
+ QuestionEngine,
308
+ QUESTION_TYPES,
309
+ PRIORITY,
310
+ createQuestion,
311
+ };
@@ -0,0 +1,315 @@
1
+ /**
2
+ * Question Templates
3
+ *
4
+ * Predefined question templates for common development scenarios.
5
+ * Used by the Adaptive Questioning Engine.
6
+ */
7
+
8
+ const { QUESTION_TYPES, PRIORITY, createQuestion } = require('./question-engine');
9
+
10
+ /**
11
+ * Project initialization questions
12
+ */
13
+ const PROJECT_QUESTIONS = [
14
+ createQuestion({
15
+ id: 'project-type',
16
+ type: QUESTION_TYPES.CLARIFYING,
17
+ priority: PRIORITY.CRITICAL,
18
+ text: 'What type of project is this?',
19
+ options: [
20
+ { value: 'web-app', label: 'Web Application' },
21
+ { value: 'api', label: 'API/Backend Service' },
22
+ { value: 'cli', label: 'Command Line Tool' },
23
+ { value: 'library', label: 'Library/Package' },
24
+ { value: 'mobile', label: 'Mobile Application' },
25
+ { value: 'other', label: 'Other' },
26
+ ],
27
+ tags: ['project', 'initialization'],
28
+ skipIfKnown: ['project.type'],
29
+ }),
30
+
31
+ createQuestion({
32
+ id: 'project-scale',
33
+ type: QUESTION_TYPES.EXPLORATORY,
34
+ priority: PRIORITY.HIGH,
35
+ text: 'What is the expected scale of this project?',
36
+ options: [
37
+ { value: 'prototype', label: 'Prototype/POC' },
38
+ { value: 'small', label: 'Small (1-5 files)' },
39
+ { value: 'medium', label: 'Medium (5-20 files)' },
40
+ { value: 'large', label: 'Large (20+ files)' },
41
+ { value: 'enterprise', label: 'Enterprise scale' },
42
+ ],
43
+ tags: ['project', 'scope'],
44
+ skipIfKnown: ['project.scale'],
45
+ }),
46
+
47
+ createQuestion({
48
+ id: 'project-team',
49
+ type: QUESTION_TYPES.EXPLORATORY,
50
+ priority: PRIORITY.MEDIUM,
51
+ text: 'Who will be working on this project?',
52
+ options: [
53
+ { value: 'solo', label: 'Just me' },
54
+ { value: 'small-team', label: 'Small team (2-5)' },
55
+ { value: 'large-team', label: 'Large team (5+)' },
56
+ { value: 'open-source', label: 'Open source community' },
57
+ ],
58
+ tags: ['project', 'team'],
59
+ skipIfKnown: ['project.team'],
60
+ }),
61
+ ];
62
+
63
+ /**
64
+ * Technical decision questions
65
+ */
66
+ const TECHNICAL_QUESTIONS = [
67
+ createQuestion({
68
+ id: 'testing-approach',
69
+ type: QUESTION_TYPES.TECHNICAL,
70
+ priority: PRIORITY.HIGH,
71
+ text: 'What testing approach do you prefer?',
72
+ options: [
73
+ { value: 'tdd', label: 'Test-Driven Development' },
74
+ { value: 'bdd', label: 'Behavior-Driven Development' },
75
+ { value: 'post-hoc', label: 'Write tests after implementation' },
76
+ { value: 'minimal', label: 'Minimal testing' },
77
+ ],
78
+ tags: ['testing', 'methodology'],
79
+ skipIfKnown: ['testing.approach'],
80
+ followUps: [
81
+ {
82
+ id: 'testing-coverage',
83
+ type: QUESTION_TYPES.PREFERENCE,
84
+ priority: PRIORITY.MEDIUM,
85
+ text: 'What level of test coverage do you target?',
86
+ options: [
87
+ { value: 'critical', label: 'Critical paths only (50-60%)' },
88
+ { value: 'standard', label: 'Standard coverage (70-80%)' },
89
+ { value: 'comprehensive', label: 'Comprehensive (80%+)' },
90
+ ],
91
+ triggerAnswer: value => value !== 'minimal',
92
+ },
93
+ ],
94
+ }),
95
+
96
+ createQuestion({
97
+ id: 'error-handling',
98
+ type: QUESTION_TYPES.TECHNICAL,
99
+ priority: PRIORITY.MEDIUM,
100
+ text: 'How should errors be handled?',
101
+ options: [
102
+ { value: 'exceptions', label: 'Throw exceptions' },
103
+ { value: 'result-types', label: 'Return Result/Either types' },
104
+ { value: 'error-codes', label: 'Return error codes' },
105
+ { value: 'mixed', label: 'Mixed approach' },
106
+ ],
107
+ tags: ['error-handling', 'patterns'],
108
+ skipIfKnown: ['error.handling'],
109
+ }),
110
+
111
+ createQuestion({
112
+ id: 'async-pattern',
113
+ type: QUESTION_TYPES.TECHNICAL,
114
+ priority: PRIORITY.MEDIUM,
115
+ text: 'Preferred async pattern?',
116
+ options: [
117
+ { value: 'async-await', label: 'async/await' },
118
+ { value: 'promises', label: 'Promises (.then/.catch)' },
119
+ { value: 'callbacks', label: 'Callbacks' },
120
+ { value: 'observables', label: 'Observables/RxJS' },
121
+ ],
122
+ tags: ['async', 'patterns'],
123
+ skipIfKnown: ['async.pattern'],
124
+ }),
125
+ ];
126
+
127
+ /**
128
+ * Preference questions
129
+ */
130
+ const PREFERENCE_QUESTIONS = [
131
+ createQuestion({
132
+ id: 'code-style',
133
+ type: QUESTION_TYPES.PREFERENCE,
134
+ priority: PRIORITY.MEDIUM,
135
+ text: 'What code style do you prefer?',
136
+ options: [
137
+ { value: 'compact', label: 'Compact (fewer lines)' },
138
+ { value: 'verbose', label: 'Verbose (explicit and clear)' },
139
+ { value: 'balanced', label: 'Balanced' },
140
+ ],
141
+ tags: ['style', 'preferences'],
142
+ skipIfKnown: ['style.code'],
143
+ }),
144
+
145
+ createQuestion({
146
+ id: 'documentation-level',
147
+ type: QUESTION_TYPES.PREFERENCE,
148
+ priority: PRIORITY.LOW,
149
+ text: 'How much documentation do you want?',
150
+ options: [
151
+ { value: 'minimal', label: 'Minimal (only complex parts)' },
152
+ { value: 'standard', label: 'Standard (public APIs)' },
153
+ { value: 'comprehensive', label: 'Comprehensive (everything)' },
154
+ ],
155
+ tags: ['documentation', 'preferences'],
156
+ skipIfKnown: ['documentation.level'],
157
+ }),
158
+
159
+ createQuestion({
160
+ id: 'naming-convention',
161
+ type: QUESTION_TYPES.PREFERENCE,
162
+ priority: PRIORITY.LOW,
163
+ text: 'Preferred naming convention for functions?',
164
+ options: [
165
+ { value: 'camelCase', label: 'camelCase' },
166
+ { value: 'snake_case', label: 'snake_case' },
167
+ { value: 'PascalCase', label: 'PascalCase' },
168
+ ],
169
+ tags: ['naming', 'preferences'],
170
+ skipIfKnown: ['naming.functions'],
171
+ }),
172
+ ];
173
+
174
+ /**
175
+ * Constraint questions
176
+ */
177
+ const CONSTRAINT_QUESTIONS = [
178
+ createQuestion({
179
+ id: 'browser-support',
180
+ type: QUESTION_TYPES.CONSTRAINT,
181
+ priority: PRIORITY.HIGH,
182
+ text: 'What browsers need to be supported?',
183
+ options: [
184
+ { value: 'modern', label: 'Modern browsers only' },
185
+ { value: 'ie11', label: 'Including IE11' },
186
+ { value: 'mobile', label: 'Mobile browsers focus' },
187
+ { value: 'all', label: 'All browsers' },
188
+ ],
189
+ tags: ['constraints', 'browser'],
190
+ skipIfKnown: ['constraints.browsers'],
191
+ askCondition: (kb) => kb.get('project.type')?.value === 'web-app',
192
+ }),
193
+
194
+ createQuestion({
195
+ id: 'node-version',
196
+ type: QUESTION_TYPES.CONSTRAINT,
197
+ priority: PRIORITY.MEDIUM,
198
+ text: 'Minimum Node.js version to support?',
199
+ options: [
200
+ { value: '16', label: 'Node 16 LTS' },
201
+ { value: '18', label: 'Node 18 LTS' },
202
+ { value: '20', label: 'Node 20 LTS' },
203
+ { value: '22', label: 'Node 22 (Current)' },
204
+ ],
205
+ tags: ['constraints', 'node'],
206
+ skipIfKnown: ['constraints.node'],
207
+ }),
208
+
209
+ createQuestion({
210
+ id: 'dependencies',
211
+ type: QUESTION_TYPES.CONSTRAINT,
212
+ priority: PRIORITY.MEDIUM,
213
+ text: 'What is your dependency philosophy?',
214
+ options: [
215
+ { value: 'minimal', label: 'Minimize dependencies' },
216
+ { value: 'pragmatic', label: 'Use well-maintained packages' },
217
+ { value: 'full', label: 'Use packages freely' },
218
+ ],
219
+ tags: ['constraints', 'dependencies'],
220
+ skipIfKnown: ['constraints.dependencies'],
221
+ }),
222
+ ];
223
+
224
+ /**
225
+ * Phase-specific questions
226
+ */
227
+ const PHASE_QUESTIONS = [
228
+ createQuestion({
229
+ id: 'phase-priority',
230
+ type: QUESTION_TYPES.CLARIFYING,
231
+ priority: PRIORITY.HIGH,
232
+ text: 'What is the priority for this phase?',
233
+ options: [
234
+ { value: 'speed', label: 'Speed (ship fast)' },
235
+ { value: 'quality', label: 'Quality (thorough testing)' },
236
+ { value: 'balanced', label: 'Balanced' },
237
+ ],
238
+ tags: ['phase', 'priority'],
239
+ }),
240
+
241
+ createQuestion({
242
+ id: 'phase-blockers',
243
+ type: QUESTION_TYPES.EXPLORATORY,
244
+ priority: PRIORITY.HIGH,
245
+ text: 'Are there any known blockers or concerns for this phase?',
246
+ options: [
247
+ { value: 'none', label: 'No known blockers' },
248
+ { value: 'technical', label: 'Technical uncertainty' },
249
+ { value: 'dependencies', label: 'Waiting on dependencies' },
250
+ { value: 'requirements', label: 'Requirements unclear' },
251
+ ],
252
+ tags: ['phase', 'blockers'],
253
+ }),
254
+ ];
255
+
256
+ /**
257
+ * Get all question templates
258
+ * @returns {object} Categorized question templates
259
+ */
260
+ function getAllTemplates() {
261
+ return {
262
+ project: PROJECT_QUESTIONS,
263
+ technical: TECHNICAL_QUESTIONS,
264
+ preference: PREFERENCE_QUESTIONS,
265
+ constraint: CONSTRAINT_QUESTIONS,
266
+ phase: PHASE_QUESTIONS,
267
+ };
268
+ }
269
+
270
+ /**
271
+ * Get questions by tags
272
+ * @param {string[]} tags - Tags to filter by
273
+ * @returns {Array} Matching questions
274
+ */
275
+ function getByTags(tags) {
276
+ const allQuestions = [
277
+ ...PROJECT_QUESTIONS,
278
+ ...TECHNICAL_QUESTIONS,
279
+ ...PREFERENCE_QUESTIONS,
280
+ ...CONSTRAINT_QUESTIONS,
281
+ ...PHASE_QUESTIONS,
282
+ ];
283
+
284
+ return allQuestions.filter(q =>
285
+ q.tags.some(t => tags.includes(t)),
286
+ );
287
+ }
288
+
289
+ /**
290
+ * Get questions by type
291
+ * @param {string} type - Question type
292
+ * @returns {Array} Matching questions
293
+ */
294
+ function getByType(type) {
295
+ const allQuestions = [
296
+ ...PROJECT_QUESTIONS,
297
+ ...TECHNICAL_QUESTIONS,
298
+ ...PREFERENCE_QUESTIONS,
299
+ ...CONSTRAINT_QUESTIONS,
300
+ ...PHASE_QUESTIONS,
301
+ ];
302
+
303
+ return allQuestions.filter(q => q.type === type);
304
+ }
305
+
306
+ module.exports = {
307
+ PROJECT_QUESTIONS,
308
+ TECHNICAL_QUESTIONS,
309
+ PREFERENCE_QUESTIONS,
310
+ CONSTRAINT_QUESTIONS,
311
+ PHASE_QUESTIONS,
312
+ getAllTemplates,
313
+ getByTags,
314
+ getByType,
315
+ };