claude-cli-advanced-starter-pack 1.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/LICENSE +21 -0
- package/OVERVIEW.md +597 -0
- package/README.md +439 -0
- package/bin/gtask.js +282 -0
- package/bin/postinstall.js +53 -0
- package/package.json +69 -0
- package/src/agents/phase-dev-templates.js +1011 -0
- package/src/agents/templates.js +668 -0
- package/src/analysis/checklist-parser.js +414 -0
- package/src/analysis/codebase.js +481 -0
- package/src/cli/menu.js +958 -0
- package/src/commands/claude-audit.js +1482 -0
- package/src/commands/claude-settings.js +2243 -0
- package/src/commands/create-agent.js +681 -0
- package/src/commands/create-command.js +337 -0
- package/src/commands/create-hook.js +262 -0
- package/src/commands/create-phase-dev/codebase-analyzer.js +813 -0
- package/src/commands/create-phase-dev/documentation-generator.js +352 -0
- package/src/commands/create-phase-dev/post-completion.js +404 -0
- package/src/commands/create-phase-dev/scale-calculator.js +344 -0
- package/src/commands/create-phase-dev/wizard.js +492 -0
- package/src/commands/create-phase-dev.js +481 -0
- package/src/commands/create-skill.js +313 -0
- package/src/commands/create.js +446 -0
- package/src/commands/decompose.js +392 -0
- package/src/commands/detect-tech-stack.js +768 -0
- package/src/commands/explore-mcp/claude-md-updater.js +252 -0
- package/src/commands/explore-mcp/mcp-installer.js +346 -0
- package/src/commands/explore-mcp/mcp-registry.js +438 -0
- package/src/commands/explore-mcp.js +638 -0
- package/src/commands/gtask-init.js +641 -0
- package/src/commands/help.js +128 -0
- package/src/commands/init.js +1890 -0
- package/src/commands/install.js +250 -0
- package/src/commands/list.js +116 -0
- package/src/commands/roadmap.js +750 -0
- package/src/commands/setup-wizard.js +482 -0
- package/src/commands/setup.js +351 -0
- package/src/commands/sync.js +534 -0
- package/src/commands/test-run.js +456 -0
- package/src/commands/test-setup.js +456 -0
- package/src/commands/validate.js +67 -0
- package/src/config/tech-stack.defaults.json +182 -0
- package/src/config/tech-stack.schema.json +502 -0
- package/src/github/client.js +359 -0
- package/src/index.js +84 -0
- package/src/templates/claude-command.js +244 -0
- package/src/templates/issue-body.js +284 -0
- package/src/testing/config.js +411 -0
- package/src/utils/template-engine.js +398 -0
- package/src/utils/validate-templates.js +223 -0
- package/src/utils.js +396 -0
- package/templates/commands/ccasp-setup.template.md +113 -0
- package/templates/commands/context-audit.template.md +97 -0
- package/templates/commands/create-task-list.template.md +382 -0
- package/templates/commands/deploy-full.template.md +261 -0
- package/templates/commands/github-task-start.template.md +99 -0
- package/templates/commands/github-update.template.md +69 -0
- package/templates/commands/happy-start.template.md +117 -0
- package/templates/commands/phase-track.template.md +142 -0
- package/templates/commands/tunnel-start.template.md +127 -0
- package/templates/commands/tunnel-stop.template.md +106 -0
- package/templates/hooks/context-guardian.template.js +173 -0
- package/templates/hooks/deployment-orchestrator.template.js +219 -0
- package/templates/hooks/github-progress-hook.template.js +197 -0
- package/templates/hooks/happy-checkpoint-manager.template.js +222 -0
- package/templates/hooks/phase-dev-enforcer.template.js +183 -0
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checklist Parser Module
|
|
3
|
+
*
|
|
4
|
+
* Parses GitHub issue markdown to extract task lists, checklists,
|
|
5
|
+
* file references, and dependencies.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Parse a GitHub issue body into structured task data
|
|
10
|
+
*/
|
|
11
|
+
export function parseIssueBody(body) {
|
|
12
|
+
const result = {
|
|
13
|
+
problemStatement: '',
|
|
14
|
+
expectedBehavior: '',
|
|
15
|
+
actualBehavior: '',
|
|
16
|
+
acceptanceCriteria: [],
|
|
17
|
+
codeAnalysis: {
|
|
18
|
+
files: [],
|
|
19
|
+
functions: [],
|
|
20
|
+
patterns: [],
|
|
21
|
+
},
|
|
22
|
+
todoList: [],
|
|
23
|
+
testScenarios: [],
|
|
24
|
+
dependencies: [],
|
|
25
|
+
raw: body,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
if (!body) return result;
|
|
29
|
+
|
|
30
|
+
const sections = splitIntoSections(body);
|
|
31
|
+
|
|
32
|
+
// Parse each section
|
|
33
|
+
for (const [title, content] of Object.entries(sections)) {
|
|
34
|
+
const titleLower = title.toLowerCase();
|
|
35
|
+
|
|
36
|
+
if (titleLower.includes('problem') || titleLower.includes('description')) {
|
|
37
|
+
result.problemStatement = content.trim();
|
|
38
|
+
} else if (titleLower.includes('expected')) {
|
|
39
|
+
result.expectedBehavior = extractBehavior(content, 'expected');
|
|
40
|
+
} else if (titleLower.includes('actual')) {
|
|
41
|
+
result.actualBehavior = extractBehavior(content, 'actual');
|
|
42
|
+
} else if (titleLower.includes('acceptance') || titleLower.includes('criteria')) {
|
|
43
|
+
result.acceptanceCriteria = parseChecklist(content);
|
|
44
|
+
} else if (titleLower.includes('code analysis') || titleLower.includes('relevant files')) {
|
|
45
|
+
result.codeAnalysis = parseCodeAnalysis(content);
|
|
46
|
+
} else if (titleLower.includes('todo') || titleLower.includes('recommended approach')) {
|
|
47
|
+
result.todoList = parseTodoList(content);
|
|
48
|
+
} else if (titleLower.includes('test')) {
|
|
49
|
+
result.testScenarios = parseTestScenarios(content);
|
|
50
|
+
} else if (titleLower.includes('dependencies')) {
|
|
51
|
+
result.dependencies = parseDependencies(content);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Also parse top-level checklists
|
|
56
|
+
const topLevelChecklists = parseChecklist(body);
|
|
57
|
+
if (topLevelChecklists.length > 0 && result.todoList.length === 0) {
|
|
58
|
+
result.todoList = topLevelChecklists;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Split markdown into sections by ## headers
|
|
66
|
+
*/
|
|
67
|
+
function splitIntoSections(body) {
|
|
68
|
+
const sections = {};
|
|
69
|
+
const lines = body.split('\n');
|
|
70
|
+
let currentSection = '_intro';
|
|
71
|
+
let currentContent = [];
|
|
72
|
+
|
|
73
|
+
for (const line of lines) {
|
|
74
|
+
const headerMatch = line.match(/^#{1,3}\s+(.+)$/);
|
|
75
|
+
if (headerMatch) {
|
|
76
|
+
// Save previous section
|
|
77
|
+
if (currentContent.length > 0) {
|
|
78
|
+
sections[currentSection] = currentContent.join('\n');
|
|
79
|
+
}
|
|
80
|
+
currentSection = headerMatch[1].trim();
|
|
81
|
+
currentContent = [];
|
|
82
|
+
} else {
|
|
83
|
+
currentContent.push(line);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Save last section
|
|
88
|
+
if (currentContent.length > 0) {
|
|
89
|
+
sections[currentSection] = currentContent.join('\n');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return sections;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Parse a checklist from markdown content
|
|
97
|
+
* Supports: - [ ], - [x], * [ ], * [x], numbered lists
|
|
98
|
+
*/
|
|
99
|
+
export function parseChecklist(content) {
|
|
100
|
+
const items = [];
|
|
101
|
+
const lines = content.split('\n');
|
|
102
|
+
|
|
103
|
+
for (let i = 0; i < lines.length; i++) {
|
|
104
|
+
const line = lines[i];
|
|
105
|
+
|
|
106
|
+
// Match checkbox patterns
|
|
107
|
+
const checkboxMatch = line.match(/^[\s]*[-*]\s*\[([ xX])\]\s*(.+)$/);
|
|
108
|
+
if (checkboxMatch) {
|
|
109
|
+
const [, checked, text] = checkboxMatch;
|
|
110
|
+
const item = parseChecklistItem(text, checked.toLowerCase() === 'x');
|
|
111
|
+
item.lineNumber = i + 1;
|
|
112
|
+
items.push(item);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Match numbered list with checkbox
|
|
117
|
+
const numberedMatch = line.match(/^[\s]*(\d+)[.)]\s*\[([ xX])\]\s*(.+)$/);
|
|
118
|
+
if (numberedMatch) {
|
|
119
|
+
const [, num, checked, text] = numberedMatch;
|
|
120
|
+
const item = parseChecklistItem(text, checked.toLowerCase() === 'x');
|
|
121
|
+
item.number = parseInt(num, 10);
|
|
122
|
+
item.lineNumber = i + 1;
|
|
123
|
+
items.push(item);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Match bold step format: **Step N**: description
|
|
128
|
+
const stepMatch = line.match(/\*\*Step\s*(\d+)\*\*[:\s]*(.+)/i);
|
|
129
|
+
if (stepMatch) {
|
|
130
|
+
const [, num, text] = stepMatch;
|
|
131
|
+
const isChecked = line.includes('[x]') || line.includes('[X]');
|
|
132
|
+
const item = parseChecklistItem(text.replace(/^\[([ xX])\]\s*/, ''), isChecked);
|
|
133
|
+
item.number = parseInt(num, 10);
|
|
134
|
+
item.lineNumber = i + 1;
|
|
135
|
+
items.push(item);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return items;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Parse a single checklist item for metadata
|
|
144
|
+
*/
|
|
145
|
+
function parseChecklistItem(text, completed = false) {
|
|
146
|
+
const item = {
|
|
147
|
+
text: text.trim(),
|
|
148
|
+
completed,
|
|
149
|
+
fileRefs: [],
|
|
150
|
+
functionRefs: [],
|
|
151
|
+
priority: null,
|
|
152
|
+
dependsOn: null,
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// Extract file references (path:line format)
|
|
156
|
+
const fileRefPattern = /`([^`]+\.[a-z]+):(\d+)`|`([^`]+\.[a-z]+)`/gi;
|
|
157
|
+
let match;
|
|
158
|
+
while ((match = fileRefPattern.exec(text)) !== null) {
|
|
159
|
+
if (match[1]) {
|
|
160
|
+
item.fileRefs.push({ file: match[1], line: parseInt(match[2], 10) });
|
|
161
|
+
} else if (match[3]) {
|
|
162
|
+
item.fileRefs.push({ file: match[3], line: null });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Extract function references
|
|
167
|
+
const funcPattern = /`(\w+)\(\)`/g;
|
|
168
|
+
while ((match = funcPattern.exec(text)) !== null) {
|
|
169
|
+
item.functionRefs.push(match[1]);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Extract priority markers
|
|
173
|
+
if (text.match(/\b(P0|critical)\b/i)) item.priority = 'P0';
|
|
174
|
+
else if (text.match(/\b(P1|high)\b/i)) item.priority = 'P1';
|
|
175
|
+
else if (text.match(/\b(P2|medium)\b/i)) item.priority = 'P2';
|
|
176
|
+
else if (text.match(/\b(P3|low)\b/i)) item.priority = 'P3';
|
|
177
|
+
|
|
178
|
+
// Extract dependency
|
|
179
|
+
const depMatch = text.match(/depends?\s+on\s+(?:step\s+)?(\d+)/i);
|
|
180
|
+
if (depMatch) {
|
|
181
|
+
item.dependsOn = parseInt(depMatch[1], 10);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return item;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Parse code analysis section
|
|
189
|
+
*/
|
|
190
|
+
function parseCodeAnalysis(content) {
|
|
191
|
+
const result = {
|
|
192
|
+
files: [],
|
|
193
|
+
functions: [],
|
|
194
|
+
patterns: [],
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// Parse markdown table
|
|
198
|
+
const tableRows = content.match(/\|[^|]+\|[^|]+\|[^|]+\|[^|]*\|/g) || [];
|
|
199
|
+
for (const row of tableRows) {
|
|
200
|
+
if (row.includes('---') || row.toLowerCase().includes('file')) continue;
|
|
201
|
+
|
|
202
|
+
const cells = row.split('|').filter(Boolean).map((c) => c.trim());
|
|
203
|
+
if (cells.length >= 3) {
|
|
204
|
+
const file = cells[0].replace(/`/g, '');
|
|
205
|
+
const line = parseInt(cells[1], 10) || null;
|
|
206
|
+
const func = cells[2].replace(/`/g, '').replace(/\(\)$/, '');
|
|
207
|
+
const purpose = cells[3] || '';
|
|
208
|
+
|
|
209
|
+
if (file && !file.includes('File')) {
|
|
210
|
+
result.files.push({ file, line, function: func, purpose });
|
|
211
|
+
if (func) {
|
|
212
|
+
result.functions.push({ name: func, file, line });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Parse bullet points for patterns
|
|
219
|
+
const patternLines = content.match(/^[-*]\s+\*\*([^*]+)\*\*[:\s]*(.+)$/gm) || [];
|
|
220
|
+
for (const line of patternLines) {
|
|
221
|
+
const match = line.match(/\*\*([^*]+)\*\*[:\s]*(.+)/);
|
|
222
|
+
if (match) {
|
|
223
|
+
result.patterns.push({ name: match[1], description: match[2] });
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return result;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Parse todo list with step structure
|
|
232
|
+
*/
|
|
233
|
+
function parseTodoList(content) {
|
|
234
|
+
const items = parseChecklist(content);
|
|
235
|
+
|
|
236
|
+
// Look for sub-items (indented bullets)
|
|
237
|
+
const lines = content.split('\n');
|
|
238
|
+
for (let i = 0; i < lines.length; i++) {
|
|
239
|
+
const line = lines[i];
|
|
240
|
+
const subItemMatch = line.match(/^\s{2,}[-*]\s+(.+)$/);
|
|
241
|
+
|
|
242
|
+
if (subItemMatch && items.length > 0) {
|
|
243
|
+
// Find parent item
|
|
244
|
+
for (let j = items.length - 1; j >= 0; j--) {
|
|
245
|
+
if (items[j].lineNumber && items[j].lineNumber < i + 1) {
|
|
246
|
+
if (!items[j].subItems) items[j].subItems = [];
|
|
247
|
+
items[j].subItems.push(subItemMatch[1].trim());
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return items;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Parse test scenarios
|
|
259
|
+
*/
|
|
260
|
+
function parseTestScenarios(content) {
|
|
261
|
+
const scenarios = [];
|
|
262
|
+
const items = parseChecklist(content);
|
|
263
|
+
|
|
264
|
+
for (const item of items) {
|
|
265
|
+
const scenario = {
|
|
266
|
+
name: item.text,
|
|
267
|
+
completed: item.completed,
|
|
268
|
+
steps: item.subItems || [],
|
|
269
|
+
expected: null,
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
// Extract "Expected:" from text or sub-items
|
|
273
|
+
const expectedMatch = item.text.match(/expected[:\s]+(.+)/i);
|
|
274
|
+
if (expectedMatch) {
|
|
275
|
+
scenario.expected = expectedMatch[1];
|
|
276
|
+
} else if (scenario.steps.length > 0) {
|
|
277
|
+
const expectedStep = scenario.steps.find((s) =>
|
|
278
|
+
s.toLowerCase().startsWith('expected')
|
|
279
|
+
);
|
|
280
|
+
if (expectedStep) {
|
|
281
|
+
scenario.expected = expectedStep.replace(/^expected[:\s]*/i, '');
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
scenarios.push(scenario);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return scenarios;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Parse dependencies section
|
|
293
|
+
*/
|
|
294
|
+
function parseDependencies(content) {
|
|
295
|
+
const deps = [];
|
|
296
|
+
const lines = content.split('\n');
|
|
297
|
+
|
|
298
|
+
for (const line of lines) {
|
|
299
|
+
const match = line.match(/step\s+(\d+)\s+depends?\s+on\s+step\s+(\d+)/i);
|
|
300
|
+
if (match) {
|
|
301
|
+
deps.push({
|
|
302
|
+
step: parseInt(match[1], 10),
|
|
303
|
+
dependsOn: parseInt(match[2], 10),
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return deps;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Extract expected or actual behavior from content
|
|
313
|
+
*/
|
|
314
|
+
function extractBehavior(content, type) {
|
|
315
|
+
// Try to find labeled line
|
|
316
|
+
const pattern = new RegExp(`\\*\\*${type}\\*\\*[:\\s]*(.+)`, 'i');
|
|
317
|
+
const match = content.match(pattern);
|
|
318
|
+
if (match) return match[1].trim();
|
|
319
|
+
|
|
320
|
+
// Otherwise return first non-empty line
|
|
321
|
+
const lines = content.split('\n').filter((l) => l.trim());
|
|
322
|
+
return lines[0]?.trim() || '';
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Convert parsed issue to Claude task list format
|
|
327
|
+
*/
|
|
328
|
+
export function toClaudeTaskList(parsed) {
|
|
329
|
+
const tasks = [];
|
|
330
|
+
|
|
331
|
+
// Add todo items as tasks
|
|
332
|
+
for (let i = 0; i < parsed.todoList.length; i++) {
|
|
333
|
+
const item = parsed.todoList[i];
|
|
334
|
+
const taskNum = item.number || i + 1;
|
|
335
|
+
|
|
336
|
+
tasks.push({
|
|
337
|
+
content: `Step ${taskNum}: ${cleanTaskText(item.text)}`,
|
|
338
|
+
activeForm: `Working on Step ${taskNum}: ${cleanTaskText(item.text)}`,
|
|
339
|
+
status: item.completed ? 'completed' : 'pending',
|
|
340
|
+
metadata: {
|
|
341
|
+
originalText: item.text,
|
|
342
|
+
fileRefs: item.fileRefs,
|
|
343
|
+
functionRefs: item.functionRefs,
|
|
344
|
+
dependsOn: item.dependsOn,
|
|
345
|
+
subItems: item.subItems,
|
|
346
|
+
},
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Add test scenarios as final tasks
|
|
351
|
+
if (parsed.testScenarios.length > 0) {
|
|
352
|
+
tasks.push({
|
|
353
|
+
content: 'Run test scenarios to validate changes',
|
|
354
|
+
activeForm: 'Running test scenarios',
|
|
355
|
+
status: 'pending',
|
|
356
|
+
metadata: {
|
|
357
|
+
scenarios: parsed.testScenarios,
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return tasks;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Clean task text for display
|
|
367
|
+
*/
|
|
368
|
+
function cleanTaskText(text) {
|
|
369
|
+
return text
|
|
370
|
+
.replace(/\*\*Step\s*\d+\*\*[:\s]*/i, '')
|
|
371
|
+
.replace(/^\[([ xX])\]\s*/, '')
|
|
372
|
+
.trim();
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Generate markdown checklist from tasks
|
|
377
|
+
*/
|
|
378
|
+
export function toMarkdownChecklist(tasks) {
|
|
379
|
+
const lines = [];
|
|
380
|
+
|
|
381
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
382
|
+
const task = tasks[i];
|
|
383
|
+
const checkbox = task.status === 'completed' ? '[x]' : '[ ]';
|
|
384
|
+
const content = task.content || task.text || '';
|
|
385
|
+
|
|
386
|
+
lines.push(`- ${checkbox} **Step ${i + 1}**: ${content}`);
|
|
387
|
+
|
|
388
|
+
// Add sub-items if present
|
|
389
|
+
if (task.metadata?.subItems) {
|
|
390
|
+
for (const sub of task.metadata.subItems) {
|
|
391
|
+
lines.push(` - ${sub}`);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return lines.join('\n');
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Calculate completion percentage
|
|
401
|
+
*/
|
|
402
|
+
export function getCompletionStats(tasks) {
|
|
403
|
+
const total = tasks.length;
|
|
404
|
+
const completed = tasks.filter(
|
|
405
|
+
(t) => t.status === 'completed' || t.completed
|
|
406
|
+
).length;
|
|
407
|
+
|
|
408
|
+
return {
|
|
409
|
+
total,
|
|
410
|
+
completed,
|
|
411
|
+
pending: total - completed,
|
|
412
|
+
percentage: total > 0 ? Math.round((completed / total) * 100) : 0,
|
|
413
|
+
};
|
|
414
|
+
}
|