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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/OVERVIEW.md +597 -0
  3. package/README.md +439 -0
  4. package/bin/gtask.js +282 -0
  5. package/bin/postinstall.js +53 -0
  6. package/package.json +69 -0
  7. package/src/agents/phase-dev-templates.js +1011 -0
  8. package/src/agents/templates.js +668 -0
  9. package/src/analysis/checklist-parser.js +414 -0
  10. package/src/analysis/codebase.js +481 -0
  11. package/src/cli/menu.js +958 -0
  12. package/src/commands/claude-audit.js +1482 -0
  13. package/src/commands/claude-settings.js +2243 -0
  14. package/src/commands/create-agent.js +681 -0
  15. package/src/commands/create-command.js +337 -0
  16. package/src/commands/create-hook.js +262 -0
  17. package/src/commands/create-phase-dev/codebase-analyzer.js +813 -0
  18. package/src/commands/create-phase-dev/documentation-generator.js +352 -0
  19. package/src/commands/create-phase-dev/post-completion.js +404 -0
  20. package/src/commands/create-phase-dev/scale-calculator.js +344 -0
  21. package/src/commands/create-phase-dev/wizard.js +492 -0
  22. package/src/commands/create-phase-dev.js +481 -0
  23. package/src/commands/create-skill.js +313 -0
  24. package/src/commands/create.js +446 -0
  25. package/src/commands/decompose.js +392 -0
  26. package/src/commands/detect-tech-stack.js +768 -0
  27. package/src/commands/explore-mcp/claude-md-updater.js +252 -0
  28. package/src/commands/explore-mcp/mcp-installer.js +346 -0
  29. package/src/commands/explore-mcp/mcp-registry.js +438 -0
  30. package/src/commands/explore-mcp.js +638 -0
  31. package/src/commands/gtask-init.js +641 -0
  32. package/src/commands/help.js +128 -0
  33. package/src/commands/init.js +1890 -0
  34. package/src/commands/install.js +250 -0
  35. package/src/commands/list.js +116 -0
  36. package/src/commands/roadmap.js +750 -0
  37. package/src/commands/setup-wizard.js +482 -0
  38. package/src/commands/setup.js +351 -0
  39. package/src/commands/sync.js +534 -0
  40. package/src/commands/test-run.js +456 -0
  41. package/src/commands/test-setup.js +456 -0
  42. package/src/commands/validate.js +67 -0
  43. package/src/config/tech-stack.defaults.json +182 -0
  44. package/src/config/tech-stack.schema.json +502 -0
  45. package/src/github/client.js +359 -0
  46. package/src/index.js +84 -0
  47. package/src/templates/claude-command.js +244 -0
  48. package/src/templates/issue-body.js +284 -0
  49. package/src/testing/config.js +411 -0
  50. package/src/utils/template-engine.js +398 -0
  51. package/src/utils/validate-templates.js +223 -0
  52. package/src/utils.js +396 -0
  53. package/templates/commands/ccasp-setup.template.md +113 -0
  54. package/templates/commands/context-audit.template.md +97 -0
  55. package/templates/commands/create-task-list.template.md +382 -0
  56. package/templates/commands/deploy-full.template.md +261 -0
  57. package/templates/commands/github-task-start.template.md +99 -0
  58. package/templates/commands/github-update.template.md +69 -0
  59. package/templates/commands/happy-start.template.md +117 -0
  60. package/templates/commands/phase-track.template.md +142 -0
  61. package/templates/commands/tunnel-start.template.md +127 -0
  62. package/templates/commands/tunnel-stop.template.md +106 -0
  63. package/templates/hooks/context-guardian.template.js +173 -0
  64. package/templates/hooks/deployment-orchestrator.template.js +219 -0
  65. package/templates/hooks/github-progress-hook.template.js +197 -0
  66. package/templates/hooks/happy-checkpoint-manager.template.js +222 -0
  67. package/templates/hooks/phase-dev-enforcer.template.js +183 -0
@@ -0,0 +1,446 @@
1
+ /**
2
+ * Create Task Command
3
+ *
4
+ * Interactive task creation with codebase analysis
5
+ */
6
+
7
+ import chalk from 'chalk';
8
+ import inquirer from 'inquirer';
9
+ import ora from 'ora';
10
+ import { showHeader, showSuccess, showError, showWarning, showInfo } from '../cli/menu.js';
11
+ import { loadConfigSync } from '../utils.js';
12
+ import { createIssue, addIssueToProject, getProjectItemId, updateProjectItemField } from '../github/client.js';
13
+ import { analyzeForIssue, detectProjectType } from '../analysis/codebase.js';
14
+ import { generateIssueBody, generateSimpleIssueBody, suggestAcceptanceCriteria } from '../templates/issue-body.js';
15
+
16
+ /**
17
+ * Label categories
18
+ */
19
+ const LABEL_CATEGORIES = {
20
+ type: [
21
+ { name: 'bug', description: 'Something isn\'t working' },
22
+ { name: 'feature', description: 'New functionality' },
23
+ { name: 'feature-update', description: 'Enhancement to existing feature' },
24
+ { name: 'refactor', description: 'Code improvement without behavior change' },
25
+ { name: 'documentation', description: 'Documentation only' },
26
+ ],
27
+ stack: [
28
+ { name: 'frontend', description: 'UI/client changes' },
29
+ { name: 'backend', description: 'API/server changes' },
30
+ ],
31
+ };
32
+
33
+ /**
34
+ * Priority options
35
+ */
36
+ const PRIORITIES = [
37
+ { name: 'P0-Critical', description: 'Production broken, blocks all users' },
38
+ { name: 'P1-High', description: 'Major feature broken, affects many users' },
39
+ { name: 'P2-Medium', description: 'Minor bug or new feature (default)' },
40
+ { name: 'P3-Low', description: 'Nice to have, polish, cleanup' },
41
+ ];
42
+
43
+ /**
44
+ * Run the create command
45
+ */
46
+ export async function runCreate(options) {
47
+ showHeader('Create GitHub Task');
48
+
49
+ // Load config
50
+ const { config, path: configPath } = loadConfigSync();
51
+
52
+ if (!config || !config.project_board?.owner) {
53
+ showError('Not configured', 'Run "gtask setup" first to configure your project.');
54
+ return;
55
+ }
56
+
57
+ const { owner, repo, project_number: projectNumber, project_id: projectId } = config.project_board;
58
+
59
+ console.log(chalk.dim(`Creating task for ${owner}/${repo}`));
60
+ if (projectNumber) {
61
+ console.log(chalk.dim(`Project board: #${projectNumber}`));
62
+ }
63
+ console.log('');
64
+
65
+ // Gather task details
66
+ const taskData = await gatherTaskDetails(options, config);
67
+
68
+ if (!taskData) {
69
+ return; // User cancelled
70
+ }
71
+
72
+ // Perform codebase analysis
73
+ let codeAnalysis = null;
74
+ if (!options.skipAnalysis) {
75
+ const analyzeSpinner = ora('Analyzing codebase...').start();
76
+ try {
77
+ // Extract keywords from title and description
78
+ const keywords = extractKeywords(taskData.title, taskData.description);
79
+ codeAnalysis = await analyzeForIssue(keywords, { maxFiles: 5 });
80
+ analyzeSpinner.succeed(`Found ${codeAnalysis.relevantFiles.length} relevant files`);
81
+ } catch (error) {
82
+ analyzeSpinner.warn('Codebase analysis skipped');
83
+ }
84
+ }
85
+
86
+ // Generate issue body
87
+ const spinner = ora('Generating issue body...').start();
88
+
89
+ const issueBody = codeAnalysis
90
+ ? generateIssueBody({
91
+ description: taskData.description,
92
+ expectedBehavior: taskData.expectedBehavior,
93
+ actualBehavior: taskData.actualBehavior,
94
+ acceptanceCriteria: taskData.acceptanceCriteria,
95
+ codeAnalysis,
96
+ todoList: generateTodoList(taskData, codeAnalysis),
97
+ testScenarios: generateTestScenarios(taskData),
98
+ priority: taskData.priority,
99
+ labels: taskData.labels,
100
+ })
101
+ : generateSimpleIssueBody({
102
+ description: taskData.description,
103
+ acceptanceCriteria: taskData.acceptanceCriteria,
104
+ });
105
+
106
+ spinner.succeed('Issue body generated');
107
+
108
+ // Preview
109
+ console.log('');
110
+ console.log(chalk.cyan('─'.repeat(60)));
111
+ console.log(chalk.bold('Preview:'));
112
+ console.log(chalk.cyan('─'.repeat(60)));
113
+ console.log(chalk.dim(issueBody.slice(0, 500) + '...'));
114
+ console.log(chalk.cyan('─'.repeat(60)));
115
+ console.log('');
116
+
117
+ // Confirm creation
118
+ const { confirmCreate } = await inquirer.prompt([
119
+ {
120
+ type: 'confirm',
121
+ name: 'confirmCreate',
122
+ message: 'Create this issue?',
123
+ default: true,
124
+ },
125
+ ]);
126
+
127
+ if (!confirmCreate) {
128
+ console.log(chalk.yellow('Cancelled.'));
129
+ return;
130
+ }
131
+
132
+ // Create the issue
133
+ const createSpinner = ora('Creating GitHub issue...').start();
134
+
135
+ const result = await createIssue(owner, repo, {
136
+ title: taskData.title,
137
+ body: issueBody,
138
+ labels: taskData.labels,
139
+ assignees: [owner],
140
+ });
141
+
142
+ if (!result.success) {
143
+ createSpinner.fail('Failed to create issue');
144
+ showError('Error', result.error);
145
+ return;
146
+ }
147
+
148
+ createSpinner.succeed(`Issue #${result.number} created`);
149
+
150
+ // Add to project board
151
+ if (projectNumber) {
152
+ const projectSpinner = ora('Adding to project board...').start();
153
+ const added = addIssueToProject(owner, projectNumber, result.url);
154
+
155
+ if (added) {
156
+ projectSpinner.succeed('Added to project board');
157
+
158
+ // Update fields if we have IDs
159
+ if (projectId && config.field_ids?.status) {
160
+ const itemId = getProjectItemId(owner, projectNumber, result.number);
161
+
162
+ if (itemId) {
163
+ // Set status to "Todo"
164
+ if (config.status_options?.todo) {
165
+ updateProjectItemField(
166
+ projectId,
167
+ itemId,
168
+ config.field_ids.status,
169
+ config.status_options.todo,
170
+ 'single-select'
171
+ );
172
+ }
173
+
174
+ // Set priority if available
175
+ if (config.field_ids?.priority && config.priority_options) {
176
+ const priorityKey = taskData.priority.toLowerCase().replace('-', '').slice(0, 2);
177
+ const priorityOptionId = config.priority_options[priorityKey];
178
+ if (priorityOptionId) {
179
+ updateProjectItemField(
180
+ projectId,
181
+ itemId,
182
+ config.field_ids.priority,
183
+ priorityOptionId,
184
+ 'single-select'
185
+ );
186
+ }
187
+ }
188
+ }
189
+ }
190
+ } else {
191
+ projectSpinner.warn('Could not add to project board');
192
+ }
193
+ }
194
+
195
+ // Success summary
196
+ showSuccess('Task Created Successfully', [
197
+ `Issue: #${result.number} - ${taskData.title}`,
198
+ `URL: ${result.url}`,
199
+ `Priority: ${taskData.priority}`,
200
+ `Labels: ${taskData.labels.join(', ')}`,
201
+ '',
202
+ 'Next: Start working or create another task',
203
+ ]);
204
+
205
+ return result;
206
+ }
207
+
208
+ /**
209
+ * Gather task details interactively
210
+ */
211
+ async function gatherTaskDetails(options, config) {
212
+ const data = {
213
+ title: options.title || '',
214
+ description: options.description || '',
215
+ priority: options.priority || 'P2-Medium',
216
+ labels: options.labels ? options.labels.split(',').map((l) => l.trim()) : [],
217
+ acceptanceCriteria: [],
218
+ expectedBehavior: '',
219
+ actualBehavior: '',
220
+ };
221
+
222
+ // Batch mode - parse from options
223
+ if (options.batch) {
224
+ if (!data.title || !data.description) {
225
+ showError('Batch mode requires --title and --description');
226
+ return null;
227
+ }
228
+ return data;
229
+ }
230
+
231
+ // Interactive mode
232
+
233
+ // Title
234
+ if (!data.title) {
235
+ const { title } = await inquirer.prompt([
236
+ {
237
+ type: 'input',
238
+ name: 'title',
239
+ message: 'Issue title:',
240
+ validate: (input) => (input.trim() ? true : 'Title is required'),
241
+ },
242
+ ]);
243
+ data.title = title.trim();
244
+ }
245
+
246
+ // Type (determines other fields)
247
+ const { issueType } = await inquirer.prompt([
248
+ {
249
+ type: 'list',
250
+ name: 'issueType',
251
+ message: 'Issue type:',
252
+ choices: LABEL_CATEGORIES.type.map((t) => ({
253
+ name: `${t.name} - ${chalk.dim(t.description)}`,
254
+ value: t.name,
255
+ })),
256
+ },
257
+ ]);
258
+ data.labels.push(issueType);
259
+
260
+ // Description
261
+ console.log('');
262
+ console.log(chalk.dim('Enter description (press Enter twice to finish):'));
263
+ const { description } = await inquirer.prompt([
264
+ {
265
+ type: 'editor',
266
+ name: 'description',
267
+ message: 'Description:',
268
+ default: data.description || '',
269
+ },
270
+ ]);
271
+ data.description = description.trim();
272
+
273
+ // Bug-specific fields
274
+ if (issueType === 'bug') {
275
+ const { expectedBehavior, actualBehavior } = await inquirer.prompt([
276
+ {
277
+ type: 'input',
278
+ name: 'expectedBehavior',
279
+ message: 'Expected behavior:',
280
+ },
281
+ {
282
+ type: 'input',
283
+ name: 'actualBehavior',
284
+ message: 'Actual behavior:',
285
+ },
286
+ ]);
287
+ data.expectedBehavior = expectedBehavior;
288
+ data.actualBehavior = actualBehavior;
289
+ }
290
+
291
+ // Stack
292
+ const { stack } = await inquirer.prompt([
293
+ {
294
+ type: 'checkbox',
295
+ name: 'stack',
296
+ message: 'Stack affected:',
297
+ choices: LABEL_CATEGORIES.stack.map((s) => ({
298
+ name: `${s.name} - ${chalk.dim(s.description)}`,
299
+ value: s.name,
300
+ })),
301
+ validate: (input) =>
302
+ input.length > 0 ? true : 'Select at least one stack',
303
+ },
304
+ ]);
305
+ data.labels.push(...stack);
306
+
307
+ // Priority
308
+ const { priority } = await inquirer.prompt([
309
+ {
310
+ type: 'list',
311
+ name: 'priority',
312
+ message: 'Priority:',
313
+ choices: PRIORITIES.map((p) => ({
314
+ name: `${p.name} - ${chalk.dim(p.description)}`,
315
+ value: p.name,
316
+ })),
317
+ default: 2, // P2-Medium
318
+ },
319
+ ]);
320
+ data.priority = priority;
321
+
322
+ // Acceptance criteria
323
+ const suggestedCriteria = suggestAcceptanceCriteria(issueType);
324
+ console.log('');
325
+ console.log(chalk.dim('Suggested acceptance criteria:'));
326
+ suggestedCriteria.forEach((c, i) => console.log(chalk.dim(` ${i + 1}. ${c}`)));
327
+
328
+ const { useSuggested } = await inquirer.prompt([
329
+ {
330
+ type: 'confirm',
331
+ name: 'useSuggested',
332
+ message: 'Use suggested acceptance criteria?',
333
+ default: true,
334
+ },
335
+ ]);
336
+
337
+ if (useSuggested) {
338
+ data.acceptanceCriteria = [...suggestedCriteria];
339
+ }
340
+
341
+ const { additionalCriteria } = await inquirer.prompt([
342
+ {
343
+ type: 'input',
344
+ name: 'additionalCriteria',
345
+ message: 'Additional acceptance criteria (comma-separated, or Enter to skip):',
346
+ },
347
+ ]);
348
+
349
+ if (additionalCriteria.trim()) {
350
+ const additional = additionalCriteria.split(',').map((c) => c.trim()).filter(Boolean);
351
+ data.acceptanceCriteria.push(...additional);
352
+ }
353
+
354
+ return data;
355
+ }
356
+
357
+ /**
358
+ * Extract keywords from title and description for codebase search
359
+ */
360
+ function extractKeywords(title, description) {
361
+ const text = `${title} ${description}`.toLowerCase();
362
+
363
+ // Remove common words
364
+ const stopWords = new Set([
365
+ 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
366
+ 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
367
+ 'should', 'may', 'might', 'must', 'shall', 'can', 'need', 'to', 'of',
368
+ 'in', 'for', 'on', 'with', 'at', 'by', 'from', 'as', 'into', 'through',
369
+ 'during', 'before', 'after', 'above', 'below', 'between', 'under',
370
+ 'again', 'further', 'then', 'once', 'here', 'there', 'when', 'where',
371
+ 'why', 'how', 'all', 'each', 'few', 'more', 'most', 'other', 'some',
372
+ 'such', 'no', 'nor', 'not', 'only', 'own', 'same', 'so', 'than', 'too',
373
+ 'very', 'just', 'and', 'but', 'if', 'or', 'because', 'until', 'while',
374
+ 'although', 'though', 'this', 'that', 'these', 'those', 'i', 'you', 'he',
375
+ 'she', 'it', 'we', 'they', 'what', 'which', 'who', 'whom', 'bug', 'fix',
376
+ 'issue', 'problem', 'error', 'broken', 'working', 'work', 'doesnt', 'dont',
377
+ ]);
378
+
379
+ // Extract words
380
+ const words = text
381
+ .replace(/[^a-z0-9\s]/g, ' ')
382
+ .split(/\s+/)
383
+ .filter((w) => w.length > 2 && !stopWords.has(w));
384
+
385
+ // Dedupe and limit
386
+ const unique = [...new Set(words)];
387
+ return unique.slice(0, 10);
388
+ }
389
+
390
+ /**
391
+ * Generate todo list from task data and analysis
392
+ */
393
+ function generateTodoList(taskData, codeAnalysis) {
394
+ const todos = [];
395
+
396
+ // Add steps based on relevant files found
397
+ if (codeAnalysis?.relevantFiles?.length > 0) {
398
+ for (const fileInfo of codeAnalysis.relevantFiles.slice(0, 3)) {
399
+ if (fileInfo.definitions?.length > 0) {
400
+ const mainDef = fileInfo.definitions[0];
401
+ todos.push({
402
+ task: `Review and update ${mainDef.name}() in ${fileInfo.file}`,
403
+ file: fileInfo.file,
404
+ details: `Line ${mainDef.line}`,
405
+ });
406
+ }
407
+ }
408
+ }
409
+
410
+ // Add testing step
411
+ todos.push({
412
+ task: 'Test changes locally',
413
+ details: 'Verify fix works in development environment',
414
+ });
415
+
416
+ // Add PR step
417
+ todos.push({
418
+ task: 'Create commit with descriptive message',
419
+ details: `Reference issue number in commit: "fix: description (#${taskData.issueNumber || 'N'})"`,
420
+ });
421
+
422
+ return todos;
423
+ }
424
+
425
+ /**
426
+ * Generate test scenarios
427
+ */
428
+ function generateTestScenarios(taskData) {
429
+ const scenarios = [];
430
+
431
+ // Basic happy path
432
+ scenarios.push({
433
+ name: 'Happy path - normal usage',
434
+ steps: ['Navigate to feature', 'Perform action', 'Verify result'],
435
+ expected: 'Feature works as expected',
436
+ });
437
+
438
+ // Edge case
439
+ scenarios.push({
440
+ name: 'Edge case - boundary conditions',
441
+ steps: ['Test with edge case input', 'Verify handling'],
442
+ expected: 'No errors, graceful handling',
443
+ });
444
+
445
+ return scenarios;
446
+ }