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,351 @@
1
+ /**
2
+ * Setup Command
3
+ *
4
+ * Interactive wizard to configure GitHub project connection
5
+ */
6
+
7
+ import chalk from 'chalk';
8
+ import inquirer from 'inquirer';
9
+ import ora from 'ora';
10
+ import { writeFileSync, existsSync, mkdirSync } from 'fs';
11
+ import { join, dirname } from 'path';
12
+ import { stringify as yamlStringify } from 'yaml';
13
+ import { showHeader, showSuccess, showError, showWarning } from '../cli/menu.js';
14
+ import {
15
+ getCurrentUser,
16
+ listRepos,
17
+ repoExists,
18
+ listProjects,
19
+ getProject,
20
+ listProjectFields,
21
+ getAllFieldOptions,
22
+ } from '../github/client.js';
23
+
24
+ /**
25
+ * Run the setup wizard
26
+ */
27
+ export async function runSetup(options) {
28
+ showHeader('GitHub Project Setup');
29
+
30
+ const config = {
31
+ project_board: {},
32
+ field_ids: {},
33
+ status_options: {},
34
+ priority_options: {},
35
+ labels: {
36
+ type: ['bug', 'feature', 'feature-update', 'refactor', 'documentation'],
37
+ stack: ['frontend', 'backend'],
38
+ priority: ['P0-Critical', 'P1-High', 'P2-Medium', 'P3-Low'],
39
+ },
40
+ };
41
+
42
+ // Step 1: Get current user
43
+ const spinner = ora('Checking GitHub authentication...').start();
44
+ const currentUser = getCurrentUser();
45
+
46
+ if (!currentUser) {
47
+ spinner.fail('Not authenticated with GitHub');
48
+ console.log('');
49
+ console.log(chalk.yellow('Run: gh auth login'));
50
+ return;
51
+ }
52
+
53
+ spinner.succeed(`Authenticated as ${chalk.bold(currentUser)}`);
54
+ console.log('');
55
+
56
+ // Step 2: Select owner (user or org)
57
+ let owner = options.owner;
58
+
59
+ if (!owner) {
60
+ const { ownerChoice } = await inquirer.prompt([
61
+ {
62
+ type: 'list',
63
+ name: 'ownerChoice',
64
+ message: 'GitHub owner (user or organization):',
65
+ choices: [
66
+ { name: `${currentUser} (your account)`, value: currentUser },
67
+ { name: 'Enter different owner...', value: '_other' },
68
+ ],
69
+ },
70
+ ]);
71
+
72
+ if (ownerChoice === '_other') {
73
+ const { customOwner } = await inquirer.prompt([
74
+ {
75
+ type: 'input',
76
+ name: 'customOwner',
77
+ message: 'Enter GitHub username or organization:',
78
+ validate: (input) => (input.trim() ? true : 'Owner is required'),
79
+ },
80
+ ]);
81
+ owner = customOwner.trim();
82
+ } else {
83
+ owner = ownerChoice;
84
+ }
85
+ }
86
+
87
+ config.project_board.owner = owner;
88
+ console.log('');
89
+
90
+ // Step 3: Select repository
91
+ let repo = options.repo;
92
+
93
+ if (!repo) {
94
+ const repoSpinner = ora(`Fetching repositories for ${owner}...`).start();
95
+ const repos = listRepos(owner, { limit: 50 });
96
+ repoSpinner.stop();
97
+
98
+ if (repos.length === 0) {
99
+ showWarning(`No repositories found for ${owner}`);
100
+ const { customRepo } = await inquirer.prompt([
101
+ {
102
+ type: 'input',
103
+ name: 'customRepo',
104
+ message: 'Enter repository name:',
105
+ validate: (input) => (input.trim() ? true : 'Repository is required'),
106
+ },
107
+ ]);
108
+ repo = customRepo.trim();
109
+ } else {
110
+ const repoChoices = repos.map((r) => ({
111
+ name: `${r.name}${r.isPrivate ? chalk.dim(' (private)') : ''} ${
112
+ r.description ? chalk.dim('- ' + r.description.slice(0, 40)) : ''
113
+ }`,
114
+ value: r.name,
115
+ }));
116
+ repoChoices.push({ name: 'Enter manually...', value: '_other' });
117
+
118
+ const { repoChoice } = await inquirer.prompt([
119
+ {
120
+ type: 'list',
121
+ name: 'repoChoice',
122
+ message: 'Select repository:',
123
+ choices: repoChoices,
124
+ pageSize: 15,
125
+ },
126
+ ]);
127
+
128
+ if (repoChoice === '_other') {
129
+ const { customRepo } = await inquirer.prompt([
130
+ {
131
+ type: 'input',
132
+ name: 'customRepo',
133
+ message: 'Enter repository name:',
134
+ validate: (input) => (input.trim() ? true : 'Repository is required'),
135
+ },
136
+ ]);
137
+ repo = customRepo.trim();
138
+ } else {
139
+ repo = repoChoice;
140
+ }
141
+ }
142
+ }
143
+
144
+ // Verify repo access
145
+ const verifySpinner = ora(`Verifying access to ${owner}/${repo}...`).start();
146
+ if (!repoExists(owner, repo)) {
147
+ verifySpinner.fail(`Cannot access ${owner}/${repo}`);
148
+ console.log(
149
+ chalk.yellow('Check that the repository exists and you have access.')
150
+ );
151
+ return;
152
+ }
153
+ verifySpinner.succeed(`Repository ${owner}/${repo} accessible`);
154
+
155
+ config.project_board.repo = repo;
156
+ console.log('');
157
+
158
+ // Step 4: Select project board
159
+ let projectNumber = options.project ? parseInt(options.project, 10) : null;
160
+
161
+ if (!projectNumber) {
162
+ const projectSpinner = ora(`Fetching projects for ${owner}...`).start();
163
+ const projects = listProjects(owner);
164
+ projectSpinner.stop();
165
+
166
+ if (projects.length === 0) {
167
+ showWarning(`No projects found for ${owner}`);
168
+ console.log(
169
+ chalk.dim('Create a project at: https://github.com/users/' + owner + '/projects')
170
+ );
171
+
172
+ const { customProject } = await inquirer.prompt([
173
+ {
174
+ type: 'input',
175
+ name: 'customProject',
176
+ message: 'Enter project number (or press Enter to skip):',
177
+ },
178
+ ]);
179
+
180
+ if (customProject.trim()) {
181
+ projectNumber = parseInt(customProject.trim(), 10);
182
+ }
183
+ } else {
184
+ const projectChoices = projects.map((p) => ({
185
+ name: `#${p.number} - ${p.title}`,
186
+ value: p.number,
187
+ }));
188
+ projectChoices.push({ name: 'Skip project board setup', value: null });
189
+
190
+ const { projectChoice } = await inquirer.prompt([
191
+ {
192
+ type: 'list',
193
+ name: 'projectChoice',
194
+ message: 'Select project board:',
195
+ choices: projectChoices,
196
+ },
197
+ ]);
198
+
199
+ projectNumber = projectChoice;
200
+ }
201
+ }
202
+
203
+ if (projectNumber) {
204
+ config.project_board.project_number = projectNumber;
205
+
206
+ // Get project ID
207
+ const projectSpinner = ora('Fetching project details...').start();
208
+ const project = getProject(owner, projectNumber);
209
+
210
+ if (project) {
211
+ config.project_board.project_id = project.id;
212
+ projectSpinner.succeed(`Project: ${project.title}`);
213
+
214
+ // Step 5: Get field IDs
215
+ console.log('');
216
+ const fieldSpinner = ora('Analyzing project fields...').start();
217
+ const fields = listProjectFields(owner, projectNumber);
218
+ fieldSpinner.stop();
219
+
220
+ if (fields.length > 0) {
221
+ console.log(chalk.dim('Found fields:'));
222
+ for (const field of fields) {
223
+ console.log(chalk.dim(` - ${field.name} (${field.id})`));
224
+ }
225
+ console.log('');
226
+
227
+ // Auto-detect common fields
228
+ const statusField = fields.find(
229
+ (f) => f.name.toLowerCase() === 'status'
230
+ );
231
+ const priorityField = fields.find(
232
+ (f) =>
233
+ f.name.toLowerCase() === 'priority' ||
234
+ f.name.toLowerCase().includes('priority')
235
+ );
236
+
237
+ if (statusField) {
238
+ config.field_ids.status = statusField.id;
239
+ console.log(chalk.green(`✓ Status field: ${statusField.id}`));
240
+ }
241
+
242
+ if (priorityField) {
243
+ config.field_ids.priority = priorityField.id;
244
+ console.log(chalk.green(`✓ Priority field: ${priorityField.id}`));
245
+ }
246
+
247
+ // Get field options via GraphQL
248
+ console.log('');
249
+ const optionsSpinner = ora('Fetching field options...').start();
250
+ const allFieldOptions = getAllFieldOptions(project.id);
251
+ optionsSpinner.stop();
252
+
253
+ for (const field of allFieldOptions) {
254
+ if (field.options && field.options.length > 0) {
255
+ console.log(chalk.dim(`\n${field.name} options:`));
256
+ for (const opt of field.options) {
257
+ console.log(chalk.dim(` - ${opt.name}: ${opt.id}`));
258
+ }
259
+
260
+ // Auto-map status options
261
+ if (field.name.toLowerCase() === 'status') {
262
+ for (const opt of field.options) {
263
+ const optLower = opt.name.toLowerCase();
264
+ if (optLower === 'todo' || optLower === 'to do') {
265
+ config.status_options.todo = opt.id;
266
+ } else if (
267
+ optLower === 'in progress' ||
268
+ optLower === 'in_progress'
269
+ ) {
270
+ config.status_options.in_progress = opt.id;
271
+ } else if (optLower === 'done' || optLower === 'completed') {
272
+ config.status_options.done = opt.id;
273
+ }
274
+ }
275
+ }
276
+
277
+ // Auto-map priority options
278
+ if (
279
+ field.name.toLowerCase() === 'priority' ||
280
+ field.name.toLowerCase().includes('priority')
281
+ ) {
282
+ for (const opt of field.options) {
283
+ const optLower = opt.name.toLowerCase();
284
+ if (optLower.includes('p0') || optLower.includes('critical')) {
285
+ config.priority_options.p0 = opt.id;
286
+ } else if (optLower.includes('p1') || optLower.includes('high')) {
287
+ config.priority_options.p1 = opt.id;
288
+ } else if (optLower.includes('p2') || optLower.includes('medium')) {
289
+ config.priority_options.p2 = opt.id;
290
+ } else if (optLower.includes('p3') || optLower.includes('low')) {
291
+ config.priority_options.p3 = opt.id;
292
+ }
293
+ }
294
+ }
295
+ }
296
+ }
297
+ }
298
+ } else {
299
+ projectSpinner.warn('Could not fetch project details');
300
+ }
301
+ }
302
+
303
+ console.log('');
304
+
305
+ // Step 6: Choose config location
306
+ const { configLocation } = await inquirer.prompt([
307
+ {
308
+ type: 'list',
309
+ name: 'configLocation',
310
+ message: 'Where should we save the configuration?',
311
+ choices: [
312
+ {
313
+ name: `${process.cwd()}/.gtaskrc ${chalk.dim('(project-local)')}`,
314
+ value: 'local',
315
+ },
316
+ {
317
+ name: `~/.gtaskrc ${chalk.dim('(global, all projects)')}`,
318
+ value: 'global',
319
+ },
320
+ ],
321
+ },
322
+ ]);
323
+
324
+ // Determine path
325
+ const configPath =
326
+ configLocation === 'global'
327
+ ? join(process.env.HOME || process.env.USERPROFILE || '', '.gtaskrc')
328
+ : join(process.cwd(), '.gtaskrc');
329
+
330
+ // Write config
331
+ const saveSpinner = ora(`Saving configuration to ${configPath}...`).start();
332
+
333
+ try {
334
+ const yamlContent = yamlStringify(config);
335
+ writeFileSync(configPath, yamlContent, 'utf8');
336
+ saveSpinner.succeed('Configuration saved');
337
+ } catch (error) {
338
+ saveSpinner.fail(`Failed to save: ${error.message}`);
339
+ return;
340
+ }
341
+
342
+ // Summary
343
+ showSuccess('Setup Complete!', [
344
+ `Owner: ${config.project_board.owner}`,
345
+ `Repo: ${config.project_board.repo}`,
346
+ `Project: #${config.project_board.project_number || 'none'}`,
347
+ `Config: ${configPath}`,
348
+ '',
349
+ 'Run "gtask create" to create your first task!',
350
+ ]);
351
+ }