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,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Install Command
|
|
3
|
+
*
|
|
4
|
+
* Install Claude Code command integration
|
|
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 } from 'path';
|
|
12
|
+
import { showHeader, showSuccess, showError, showWarning } from '../cli/menu.js';
|
|
13
|
+
import { loadConfigSync } from '../utils.js';
|
|
14
|
+
import { generateClaudeCommand, generateMinimalClaudeCommand } from '../templates/claude-command.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Run the install command
|
|
18
|
+
*/
|
|
19
|
+
export async function runInstall(options) {
|
|
20
|
+
showHeader('Install Claude Code Integration');
|
|
21
|
+
|
|
22
|
+
// Load config if available
|
|
23
|
+
const { config } = loadConfigSync();
|
|
24
|
+
|
|
25
|
+
// Determine target path
|
|
26
|
+
let targetPath = options.path;
|
|
27
|
+
|
|
28
|
+
if (!targetPath) {
|
|
29
|
+
// Try to find .claude/commands/ directory
|
|
30
|
+
const possiblePaths = [
|
|
31
|
+
join(process.cwd(), '.claude', 'commands'),
|
|
32
|
+
join(process.cwd(), '.claude'),
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
for (const p of possiblePaths) {
|
|
36
|
+
if (existsSync(p)) {
|
|
37
|
+
targetPath = p.endsWith('commands') ? p : join(p, 'commands');
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!targetPath) {
|
|
43
|
+
console.log(chalk.dim('No .claude/commands/ directory found.'));
|
|
44
|
+
|
|
45
|
+
const { createDir } = await inquirer.prompt([
|
|
46
|
+
{
|
|
47
|
+
type: 'confirm',
|
|
48
|
+
name: 'createDir',
|
|
49
|
+
message: 'Create .claude/commands/ directory?',
|
|
50
|
+
default: true,
|
|
51
|
+
},
|
|
52
|
+
]);
|
|
53
|
+
|
|
54
|
+
if (createDir) {
|
|
55
|
+
targetPath = join(process.cwd(), '.claude', 'commands');
|
|
56
|
+
mkdirSync(targetPath, { recursive: true });
|
|
57
|
+
console.log(chalk.green(`✓ Created ${targetPath}`));
|
|
58
|
+
} else {
|
|
59
|
+
showError('No target directory');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Check if command already exists
|
|
66
|
+
const commandFile = join(targetPath, 'github-create-task.md');
|
|
67
|
+
if (existsSync(commandFile) && !options.force) {
|
|
68
|
+
showWarning(`Command already exists: ${commandFile}`);
|
|
69
|
+
|
|
70
|
+
const { overwrite } = await inquirer.prompt([
|
|
71
|
+
{
|
|
72
|
+
type: 'confirm',
|
|
73
|
+
name: 'overwrite',
|
|
74
|
+
message: 'Overwrite existing command?',
|
|
75
|
+
default: false,
|
|
76
|
+
},
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
if (!overwrite) {
|
|
80
|
+
console.log(chalk.yellow('Cancelled.'));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Generate command content
|
|
86
|
+
let commandContent;
|
|
87
|
+
|
|
88
|
+
if (config?.project_board) {
|
|
89
|
+
// Full command with project configuration
|
|
90
|
+
const { commandType } = await inquirer.prompt([
|
|
91
|
+
{
|
|
92
|
+
type: 'list',
|
|
93
|
+
name: 'commandType',
|
|
94
|
+
message: 'Command type:',
|
|
95
|
+
choices: [
|
|
96
|
+
{
|
|
97
|
+
name: 'Full (comprehensive with all features)',
|
|
98
|
+
value: 'full',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'Minimal (basic issue creation)',
|
|
102
|
+
value: 'minimal',
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
]);
|
|
107
|
+
|
|
108
|
+
const templateConfig = {
|
|
109
|
+
owner: config.project_board.owner,
|
|
110
|
+
repo: config.project_board.repo,
|
|
111
|
+
projectNumber: config.project_board.project_number,
|
|
112
|
+
projectId: config.project_board.project_id,
|
|
113
|
+
fieldIds: config.field_ids,
|
|
114
|
+
statusOptions: config.status_options,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
commandContent =
|
|
118
|
+
commandType === 'full'
|
|
119
|
+
? generateClaudeCommand(templateConfig)
|
|
120
|
+
: generateMinimalClaudeCommand(templateConfig);
|
|
121
|
+
} else {
|
|
122
|
+
// Prompt for basic info
|
|
123
|
+
showWarning('No gtask configuration found. Creating command with placeholders.');
|
|
124
|
+
|
|
125
|
+
const { owner, repo, projectNumber } = await inquirer.prompt([
|
|
126
|
+
{
|
|
127
|
+
type: 'input',
|
|
128
|
+
name: 'owner',
|
|
129
|
+
message: 'GitHub owner (username or org):',
|
|
130
|
+
default: 'YOUR_USERNAME',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
type: 'input',
|
|
134
|
+
name: 'repo',
|
|
135
|
+
message: 'Repository name:',
|
|
136
|
+
default: 'YOUR_REPO',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
type: 'input',
|
|
140
|
+
name: 'projectNumber',
|
|
141
|
+
message: 'Project board number (or Enter to skip):',
|
|
142
|
+
default: '1',
|
|
143
|
+
},
|
|
144
|
+
]);
|
|
145
|
+
|
|
146
|
+
commandContent = generateMinimalClaudeCommand({
|
|
147
|
+
owner,
|
|
148
|
+
repo,
|
|
149
|
+
projectNumber: parseInt(projectNumber, 10) || 1,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Write the command file
|
|
154
|
+
const spinner = ora(`Writing ${commandFile}...`).start();
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
// Ensure directory exists
|
|
158
|
+
mkdirSync(targetPath, { recursive: true });
|
|
159
|
+
writeFileSync(commandFile, commandContent, 'utf8');
|
|
160
|
+
spinner.succeed('Command installed');
|
|
161
|
+
} catch (error) {
|
|
162
|
+
spinner.fail(`Failed to write: ${error.message}`);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
showSuccess('Claude Code Integration Installed!', [
|
|
167
|
+
`Command file: ${commandFile}`,
|
|
168
|
+
'',
|
|
169
|
+
'Usage in Claude Code:',
|
|
170
|
+
' /github-create-task',
|
|
171
|
+
'',
|
|
172
|
+
'The command will guide you through:',
|
|
173
|
+
' - Issue title and description',
|
|
174
|
+
' - Labels and priority selection',
|
|
175
|
+
' - Codebase analysis (via Claude)',
|
|
176
|
+
' - Issue creation and project board update',
|
|
177
|
+
]);
|
|
178
|
+
|
|
179
|
+
// Also create config template if not exists
|
|
180
|
+
const configTemplatePath = join(targetPath, '..', 'config', 'github-field-mappings.template.yaml');
|
|
181
|
+
if (!existsSync(configTemplatePath)) {
|
|
182
|
+
const { createTemplate } = await inquirer.prompt([
|
|
183
|
+
{
|
|
184
|
+
type: 'confirm',
|
|
185
|
+
name: 'createTemplate',
|
|
186
|
+
message: 'Create configuration template file?',
|
|
187
|
+
default: true,
|
|
188
|
+
},
|
|
189
|
+
]);
|
|
190
|
+
|
|
191
|
+
if (createTemplate) {
|
|
192
|
+
const configDir = join(targetPath, '..', 'config');
|
|
193
|
+
mkdirSync(configDir, { recursive: true });
|
|
194
|
+
|
|
195
|
+
const templateContent = generateConfigTemplate(config);
|
|
196
|
+
writeFileSync(configTemplatePath, templateContent, 'utf8');
|
|
197
|
+
console.log(chalk.green(`✓ Created ${configTemplatePath}`));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Generate config template content
|
|
204
|
+
*/
|
|
205
|
+
function generateConfigTemplate(existingConfig) {
|
|
206
|
+
const config = existingConfig?.project_board || {};
|
|
207
|
+
|
|
208
|
+
return `# GitHub Project Configuration Template
|
|
209
|
+
# Copy this to github-field-mappings.yaml and fill in your values
|
|
210
|
+
|
|
211
|
+
project_board:
|
|
212
|
+
owner: "${config.owner || 'YOUR_GITHUB_USERNAME'}"
|
|
213
|
+
repo: "${config.repo || 'YOUR_REPO_NAME'}"
|
|
214
|
+
project_number: ${config.project_number || 1}
|
|
215
|
+
project_id: "${config.project_id || 'PVT_YOUR_PROJECT_ID'}"
|
|
216
|
+
|
|
217
|
+
field_ids:
|
|
218
|
+
# Get field IDs via: gh project field-list <number> --owner <owner> --format json
|
|
219
|
+
status: "${existingConfig?.field_ids?.status || 'PVTSSF_YOUR_STATUS_FIELD_ID'}"
|
|
220
|
+
priority: "${existingConfig?.field_ids?.priority || 'PVTSSF_YOUR_PRIORITY_FIELD_ID'}"
|
|
221
|
+
|
|
222
|
+
status_options:
|
|
223
|
+
# Get option IDs via GraphQL (see README)
|
|
224
|
+
todo: "${existingConfig?.status_options?.todo || 'YOUR_TODO_OPTION_ID'}"
|
|
225
|
+
in_progress: "${existingConfig?.status_options?.in_progress || 'YOUR_IN_PROGRESS_OPTION_ID'}"
|
|
226
|
+
done: "${existingConfig?.status_options?.done || 'YOUR_DONE_OPTION_ID'}"
|
|
227
|
+
|
|
228
|
+
priority_options:
|
|
229
|
+
p0: "${existingConfig?.priority_options?.p0 || ''}"
|
|
230
|
+
p1: "${existingConfig?.priority_options?.p1 || ''}"
|
|
231
|
+
p2: "${existingConfig?.priority_options?.p2 || ''}"
|
|
232
|
+
p3: "${existingConfig?.priority_options?.p3 || ''}"
|
|
233
|
+
|
|
234
|
+
labels:
|
|
235
|
+
type:
|
|
236
|
+
- bug
|
|
237
|
+
- feature
|
|
238
|
+
- feature-update
|
|
239
|
+
- refactor
|
|
240
|
+
- documentation
|
|
241
|
+
stack:
|
|
242
|
+
- frontend
|
|
243
|
+
- backend
|
|
244
|
+
priority:
|
|
245
|
+
- P0-Critical
|
|
246
|
+
- P1-High
|
|
247
|
+
- P2-Medium
|
|
248
|
+
- P3-Low
|
|
249
|
+
`;
|
|
250
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List Command
|
|
3
|
+
*
|
|
4
|
+
* List recent tasks/issues
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import ora from 'ora';
|
|
9
|
+
import { showHeader, showError } from '../cli/menu.js';
|
|
10
|
+
import { loadConfigSync, truncate } from '../utils.js';
|
|
11
|
+
import { listIssues, getCurrentUser } from '../github/client.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Run the list command
|
|
15
|
+
*/
|
|
16
|
+
export async function runList(options) {
|
|
17
|
+
showHeader('Recent Tasks');
|
|
18
|
+
|
|
19
|
+
// Load config
|
|
20
|
+
const { config } = loadConfigSync();
|
|
21
|
+
|
|
22
|
+
if (!config || !config.project_board?.owner) {
|
|
23
|
+
showError('Not configured', 'Run "gtask setup" first.');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const { owner, repo } = config.project_board;
|
|
28
|
+
const limit = parseInt(options.limit, 10) || 10;
|
|
29
|
+
const state = options.status || 'open';
|
|
30
|
+
|
|
31
|
+
let assignee = null;
|
|
32
|
+
if (options.mine) {
|
|
33
|
+
assignee = getCurrentUser();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
console.log(chalk.dim(`Fetching issues from ${owner}/${repo}...`));
|
|
37
|
+
console.log('');
|
|
38
|
+
|
|
39
|
+
const spinner = ora('Loading issues...').start();
|
|
40
|
+
const issues = listIssues(owner, repo, { limit, state, assignee });
|
|
41
|
+
spinner.stop();
|
|
42
|
+
|
|
43
|
+
if (issues.length === 0) {
|
|
44
|
+
console.log(chalk.yellow('No issues found.'));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Display issues in table format
|
|
49
|
+
console.log(
|
|
50
|
+
chalk.bold(
|
|
51
|
+
`${chalk.cyan('#'.padEnd(6))} ${chalk.white('Title'.padEnd(50))} ${chalk.dim('Labels'.padEnd(20))} ${chalk.dim('Created')}`
|
|
52
|
+
)
|
|
53
|
+
);
|
|
54
|
+
console.log(chalk.dim('─'.repeat(100)));
|
|
55
|
+
|
|
56
|
+
for (const issue of issues) {
|
|
57
|
+
const number = `#${issue.number}`.padEnd(6);
|
|
58
|
+
const title = truncate(issue.title, 48).padEnd(50);
|
|
59
|
+
const labels = issue.labels
|
|
60
|
+
.map((l) => l.name)
|
|
61
|
+
.slice(0, 2)
|
|
62
|
+
.join(', ')
|
|
63
|
+
.padEnd(20);
|
|
64
|
+
const created = formatDate(issue.createdAt);
|
|
65
|
+
|
|
66
|
+
// Color based on state/labels
|
|
67
|
+
let numberColor = chalk.cyan;
|
|
68
|
+
if (issue.labels.some((l) => l.name.includes('P0') || l.name.includes('Critical'))) {
|
|
69
|
+
numberColor = chalk.red;
|
|
70
|
+
} else if (issue.labels.some((l) => l.name.includes('P1') || l.name.includes('High'))) {
|
|
71
|
+
numberColor = chalk.yellow;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
console.log(
|
|
75
|
+
`${numberColor(number)} ${chalk.white(title)} ${chalk.dim(labels)} ${chalk.dim(created)}`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log('');
|
|
80
|
+
console.log(chalk.dim(`Showing ${issues.length} ${state} issues`));
|
|
81
|
+
|
|
82
|
+
// Quick actions hint
|
|
83
|
+
console.log('');
|
|
84
|
+
console.log(chalk.dim('Quick actions:'));
|
|
85
|
+
console.log(chalk.dim(` gh issue view <number> --repo ${owner}/${repo}`));
|
|
86
|
+
console.log(chalk.dim(` gh issue edit <number> --repo ${owner}/${repo}`));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Format date to relative time
|
|
91
|
+
*/
|
|
92
|
+
function formatDate(isoDate) {
|
|
93
|
+
const date = new Date(isoDate);
|
|
94
|
+
const now = new Date();
|
|
95
|
+
const diffMs = now - date;
|
|
96
|
+
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
|
97
|
+
|
|
98
|
+
if (diffDays === 0) {
|
|
99
|
+
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
|
100
|
+
if (diffHours === 0) {
|
|
101
|
+
const diffMinutes = Math.floor(diffMs / (1000 * 60));
|
|
102
|
+
return `${diffMinutes}m ago`;
|
|
103
|
+
}
|
|
104
|
+
return `${diffHours}h ago`;
|
|
105
|
+
} else if (diffDays === 1) {
|
|
106
|
+
return 'yesterday';
|
|
107
|
+
} else if (diffDays < 7) {
|
|
108
|
+
return `${diffDays}d ago`;
|
|
109
|
+
} else if (diffDays < 30) {
|
|
110
|
+
const weeks = Math.floor(diffDays / 7);
|
|
111
|
+
return `${weeks}w ago`;
|
|
112
|
+
} else {
|
|
113
|
+
const months = Math.floor(diffDays / 30);
|
|
114
|
+
return `${months}mo ago`;
|
|
115
|
+
}
|
|
116
|
+
}
|