claude-flow-novice 1.5.2 ā 1.5.4
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/.claude/agents/SPARSE_LANGUAGE_FINDINGS.md +991 -0
- package/.claude/agents/architecture/system-architect.md +3 -44
- package/.claude/agents/benchmarking-tests/test-agent-code-heavy.md +747 -0
- package/.claude/agents/benchmarking-tests/test-agent-metadata.md +181 -0
- package/.claude/agents/benchmarking-tests/test-agent-minimal.md +67 -0
- package/.claude/agents/data/ml/data-ml-model.md +5 -119
- package/.claude/agents/development/backend/dev-backend-api.md +4 -115
- package/.claude/agents/devops/ci-cd/ops-cicd-github.md +4 -114
- package/.claude/agents/documentation/api-docs/docs-api-openapi.md +4 -113
- package/.claude/agents/github/multi-repo-swarm.md +1 -28
- package/.claude/agents/github/pr-manager.md +1 -29
- package/.claude/agents/github/project-board-sync.md +1 -32
- package/.claude/agents/github/release-manager.md +1 -32
- package/.claude/agents/github/release-swarm.md +1 -33
- package/.claude/agents/github/repo-architect.md +1 -34
- package/.claude/agents/github/swarm-issue.md +1 -26
- package/.claude/agents/github/swarm-pr.md +1 -30
- package/.claude/agents/github/sync-coordinator.md +1 -30
- package/.claude/agents/github/workflow-automation.md +1 -31
- package/.claude/agents/neural/neural-pattern-agent.md +2 -50
- package/.claude/agents/specialized/CODER_AGENT_GUIDELINES.md +1245 -0
- package/.claude/agents/specialized/mobile/spec-mobile-react-native.md +6 -142
- package/.claude/agents/sublinear/consciousness-evolution-agent.md +2 -18
- package/.claude/agents/sublinear/matrix-solver-agent.md +2 -16
- package/.claude/agents/sublinear/nanosecond-scheduler-agent.md +2 -19
- package/.claude/agents/sublinear/pagerank-agent.md +2 -19
- package/.claude/agents/sublinear/phi-calculator-agent.md +2 -19
- package/.claude/agents/sublinear/psycho-symbolic-agent.md +2 -19
- package/.claude/agents/sublinear/sublinear.md +2 -1
- package/.claude/agents/sublinear/temporal-advantage-agent.md +2 -16
- package/.claude/agents/testing/e2e/playwright-agent.md +7 -0
- package/.claude-flow-novice/.claude/agents/SPARSE_LANGUAGE_FINDINGS.md +991 -0
- package/.claude-flow-novice/.claude/agents/architecture/system-architect.md +3 -44
- package/.claude-flow-novice/.claude/agents/benchmarking-tests/test-agent-code-heavy.md +747 -0
- package/.claude-flow-novice/.claude/agents/benchmarking-tests/test-agent-metadata.md +181 -0
- package/.claude-flow-novice/.claude/agents/benchmarking-tests/test-agent-minimal.md +67 -0
- package/.claude-flow-novice/.claude/agents/data/ml/data-ml-model.md +5 -119
- package/.claude-flow-novice/.claude/agents/development/backend/dev-backend-api.md +4 -115
- package/.claude-flow-novice/.claude/agents/devops/ci-cd/ops-cicd-github.md +4 -114
- package/.claude-flow-novice/.claude/agents/documentation/api-docs/docs-api-openapi.md +4 -113
- package/.claude-flow-novice/.claude/agents/github/multi-repo-swarm.md +1 -28
- package/.claude-flow-novice/.claude/agents/github/pr-manager.md +1 -29
- package/.claude-flow-novice/.claude/agents/github/project-board-sync.md +1 -32
- package/.claude-flow-novice/.claude/agents/github/release-manager.md +1 -32
- package/.claude-flow-novice/.claude/agents/github/release-swarm.md +1 -33
- package/.claude-flow-novice/.claude/agents/github/repo-architect.md +1 -34
- package/.claude-flow-novice/.claude/agents/github/swarm-issue.md +1 -26
- package/.claude-flow-novice/.claude/agents/github/swarm-pr.md +1 -30
- package/.claude-flow-novice/.claude/agents/github/sync-coordinator.md +1 -30
- package/.claude-flow-novice/.claude/agents/github/workflow-automation.md +1 -31
- package/.claude-flow-novice/.claude/agents/neural/neural-pattern-agent.md +2 -50
- package/.claude-flow-novice/.claude/agents/specialized/CODER_AGENT_GUIDELINES.md +1245 -0
- package/.claude-flow-novice/.claude/agents/specialized/mobile/spec-mobile-react-native.md +6 -142
- package/.claude-flow-novice/.claude/agents/sublinear/consciousness-evolution-agent.md +2 -18
- package/.claude-flow-novice/.claude/agents/sublinear/matrix-solver-agent.md +2 -16
- package/.claude-flow-novice/.claude/agents/sublinear/nanosecond-scheduler-agent.md +2 -19
- package/.claude-flow-novice/.claude/agents/sublinear/pagerank-agent.md +2 -19
- package/.claude-flow-novice/.claude/agents/sublinear/phi-calculator-agent.md +2 -19
- package/.claude-flow-novice/.claude/agents/sublinear/psycho-symbolic-agent.md +2 -19
- package/.claude-flow-novice/.claude/agents/sublinear/sublinear.md +2 -1
- package/.claude-flow-novice/.claude/agents/sublinear/temporal-advantage-agent.md +2 -16
- package/.claude-flow-novice/.claude/agents/testing/e2e/playwright-agent.md +7 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/CLAUDE.md +188 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/claude-flow-universal +81 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/claude-flow.bat +18 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/claude-flow.ps1 +24 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/claude-md.js +982 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/analysis/bottleneck-detect.md +162 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/automation/auto-agent.md +122 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/coordination/swarm-init.md +85 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/github/github-swarm.md +121 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/helpers/standard-checkpoint-hooks.sh +179 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/hooks/notification.md +113 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/hooks/post-command.md +116 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/hooks/post-edit.md +117 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/hooks/post-task.md +112 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/hooks/pre-command.md +113 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/hooks/pre-edit.md +113 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/hooks/pre-search.md +112 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/hooks/pre-task.md +111 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/hooks/session-end.md +118 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/hooks/session-restore.md +118 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/commands/hooks/session-start.md +117 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/coordination-md.js +340 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/coordination.md +16 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/enhanced-templates.js +2347 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/github-safe-enhanced.js +331 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/github-safe.js +106 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/index.js +1896 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/memory-bank-md.js +259 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/memory-bank.md +16 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/readme-files.js +72 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/safe-hook-patterns.js +430 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/settings.json +109 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/settings.json.enhanced +35 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/sparc-modes.js +1401 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/CLAUDE.md +188 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/claude-flow-universal +81 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/claude-flow.bat +18 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/claude-flow.ps1 +24 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/claude-md.js +982 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/analysis/bottleneck-detect.md +162 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/automation/auto-agent.md +122 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/coordination/swarm-init.md +85 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/github/github-swarm.md +121 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/helpers/standard-checkpoint-hooks.sh +179 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/hooks/notification.md +113 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/hooks/post-command.md +116 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/hooks/post-edit.md +117 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/hooks/post-task.md +112 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/hooks/pre-command.md +113 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/hooks/pre-edit.md +113 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/hooks/pre-search.md +112 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/hooks/pre-task.md +111 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/hooks/session-end.md +118 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/hooks/session-restore.md +118 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/commands/hooks/session-start.md +117 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/coordination-md.js +340 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/coordination.md +16 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/enhanced-templates.js +2347 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/github-safe-enhanced.js +331 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/github-safe.js +106 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/memory-bank-md.js +259 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/memory-bank.md +16 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/readme-files.js +72 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/safe-hook-patterns.js +430 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/settings.json +109 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/settings.json.enhanced +35 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/sparc-modes.js +1401 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/templates/verification-claude-md.js +432 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init/verification-claude-md.js +432 -0
- package/.claude-flow-novice/dist/src/cli/simple-commands/init.js +4 -0
- package/.claude-flow-novice/dist/src/slash-commands/benchmark-prompts.js +281 -0
- package/CLAUDE.md +1927 -127
- package/package.json +3 -3
- package/src/cli/simple-commands/init/index.js +39 -4
- package/src/cli/simple-commands/init/templates/CLAUDE.md +8 -10
- package/src/slash-commands/benchmark-prompts.js +281 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Enhanced Safe GitHub CLI Helper - Production Ready
|
|
5
|
+
* Uses the comprehensive GitHubCliSafe wrapper for secure command execution
|
|
6
|
+
*
|
|
7
|
+
* Prevents:
|
|
8
|
+
* - Timeout issues with large content
|
|
9
|
+
* - Command injection attacks
|
|
10
|
+
* - Process resource leaks
|
|
11
|
+
* - Rate limiting issues
|
|
12
|
+
* - Input validation bypasses
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* ./github-safe-enhanced.js issue comment 123 "Message with `backticks` and $(dangerous) content"
|
|
16
|
+
* ./github-safe-enhanced.js pr create --title "Title" --body "Complex body with special chars"
|
|
17
|
+
* ./github-safe-enhanced.js issue create --title "Bug Report" --body "Long description..." --labels "bug,urgent"
|
|
18
|
+
* ./github-safe-enhanced.js release create v1.0.0 --title "Release v1.0.0" --body "Release notes..."
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
// Import the production-ready GitHub CLI safety wrapper
|
|
22
|
+
import {
|
|
23
|
+
githubCli,
|
|
24
|
+
GitHubCliError,
|
|
25
|
+
GitHubCliTimeoutError,
|
|
26
|
+
GitHubCliValidationError,
|
|
27
|
+
} from '../../../utils/github-cli-safety-wrapper.js';
|
|
28
|
+
|
|
29
|
+
const args = process.argv.slice(2);
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Show help message
|
|
33
|
+
*/
|
|
34
|
+
function showHelp() {
|
|
35
|
+
console.log(`
|
|
36
|
+
š”ļø Enhanced Safe GitHub CLI Helper
|
|
37
|
+
|
|
38
|
+
FEATURES:
|
|
39
|
+
ā
Injection attack prevention
|
|
40
|
+
ā
Timeout handling with cleanup
|
|
41
|
+
ā
Input validation and sanitization
|
|
42
|
+
ā
Rate limiting protection
|
|
43
|
+
ā
Comprehensive error handling
|
|
44
|
+
ā
Process resource management
|
|
45
|
+
|
|
46
|
+
USAGE:
|
|
47
|
+
./github-safe-enhanced.js <command> <subcommand> [arguments] [options]
|
|
48
|
+
|
|
49
|
+
COMMANDS:
|
|
50
|
+
Issue Operations:
|
|
51
|
+
issue create --title "Title" --body "Body" [--labels "label1,label2"] [--assignees "user1,user2"]
|
|
52
|
+
issue comment <number> "Comment body"
|
|
53
|
+
|
|
54
|
+
Pull Request Operations:
|
|
55
|
+
pr create --title "Title" --body "Body" [--base branch] [--head branch] [--draft]
|
|
56
|
+
pr comment <number> "Comment body"
|
|
57
|
+
|
|
58
|
+
Release Operations:
|
|
59
|
+
release create <tag> --title "Title" --body "Body" [--prerelease] [--draft]
|
|
60
|
+
|
|
61
|
+
OPTIONS:
|
|
62
|
+
--timeout <ms> Override default timeout (30000ms)
|
|
63
|
+
--verbose Enable detailed logging
|
|
64
|
+
--dry-run Show what would be executed without running
|
|
65
|
+
--help Show this help message
|
|
66
|
+
|
|
67
|
+
EXAMPLES:
|
|
68
|
+
# Create issue with special characters safely
|
|
69
|
+
./github-safe-enhanced.js issue create \\
|
|
70
|
+
--title "Bug: Login fails with special chars" \\
|
|
71
|
+
--body "Steps: 1. Enter \`user@domain.com\` 2. Use password with \$(special) chars" \\
|
|
72
|
+
--labels "bug,high-priority"
|
|
73
|
+
|
|
74
|
+
# Add comment with code blocks
|
|
75
|
+
./github-safe-enhanced.js issue comment 123 \\
|
|
76
|
+
"Fixed in commit abc123. Test with: \`npm test && npm run build\`"
|
|
77
|
+
|
|
78
|
+
# Create PR with complex body
|
|
79
|
+
./github-safe-enhanced.js pr create \\
|
|
80
|
+
--title "Feature: Add authentication" \\
|
|
81
|
+
--body "## Changes\\n- Added JWT auth\\n- Updated tests\\n\\n\`\`\`js\\nconst token = jwt.sign(payload);\\n\`\`\`" \\
|
|
82
|
+
--base main --head feature/auth
|
|
83
|
+
|
|
84
|
+
# Create release with detailed notes
|
|
85
|
+
./github-safe-enhanced.js release create v2.1.0 \\
|
|
86
|
+
--title "Version 2.1.0 - Security Update" \\
|
|
87
|
+
--body "## Features\\n- Enhanced security\\n- Bug fixes\\n\\n## Breaking Changes\\nNone"
|
|
88
|
+
|
|
89
|
+
SECURITY FEATURES:
|
|
90
|
+
š Blocks dangerous patterns: \$(cmd), \`cmd\`, eval(), exec()
|
|
91
|
+
š Prevents command chaining: &&, ||, ;
|
|
92
|
+
š Validates file sizes and input lengths
|
|
93
|
+
š Uses secure temporary files with restricted permissions
|
|
94
|
+
š Implements proper process cleanup and timeout handling
|
|
95
|
+
`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Parse command line arguments into structured format
|
|
100
|
+
*/
|
|
101
|
+
function parseArguments(args) {
|
|
102
|
+
if (args.length === 0 || args.includes('--help')) {
|
|
103
|
+
showHelp();
|
|
104
|
+
process.exit(0);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const [command, subcommand, ...restArgs] = args;
|
|
108
|
+
const options = {};
|
|
109
|
+
const positionalArgs = [];
|
|
110
|
+
|
|
111
|
+
// Parse flags and options
|
|
112
|
+
for (let i = 0; i < restArgs.length; i++) {
|
|
113
|
+
const arg = restArgs[i];
|
|
114
|
+
|
|
115
|
+
if (arg.startsWith('--')) {
|
|
116
|
+
const flagName = arg.substring(2);
|
|
117
|
+
const nextArg = restArgs[i + 1];
|
|
118
|
+
|
|
119
|
+
if (nextArg && !nextArg.startsWith('--')) {
|
|
120
|
+
options[flagName] = nextArg;
|
|
121
|
+
i++; // Skip the next argument
|
|
122
|
+
} else {
|
|
123
|
+
options[flagName] = true;
|
|
124
|
+
}
|
|
125
|
+
} else {
|
|
126
|
+
positionalArgs.push(arg);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return { command, subcommand, positionalArgs, options };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Execute GitHub CLI command safely
|
|
135
|
+
*/
|
|
136
|
+
async function executeCommand(command, subcommand, positionalArgs, options) {
|
|
137
|
+
try {
|
|
138
|
+
// Handle dry-run mode
|
|
139
|
+
if (options['dry-run']) {
|
|
140
|
+
console.log('š DRY RUN MODE - Would execute:');
|
|
141
|
+
console.log(`Command: ${command} ${subcommand}`);
|
|
142
|
+
console.log(`Arguments:`, positionalArgs);
|
|
143
|
+
console.log(`Options:`, options);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Configure GitHub CLI wrapper
|
|
148
|
+
const cliOptions = {
|
|
149
|
+
timeout: parseInt(options.timeout) || 30000,
|
|
150
|
+
enableLogging: options.verbose || false,
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
let result;
|
|
154
|
+
|
|
155
|
+
// Route to appropriate method based on command
|
|
156
|
+
if (command === 'issue') {
|
|
157
|
+
result = await handleIssueCommand(subcommand, positionalArgs, options, cliOptions);
|
|
158
|
+
} else if (command === 'pr') {
|
|
159
|
+
result = await handlePRCommand(subcommand, positionalArgs, options, cliOptions);
|
|
160
|
+
} else if (command === 'release') {
|
|
161
|
+
result = await handleReleaseCommand(subcommand, positionalArgs, options, cliOptions);
|
|
162
|
+
} else {
|
|
163
|
+
throw new Error(`Unsupported command: ${command}`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Output result
|
|
167
|
+
console.log('ā
Command executed successfully');
|
|
168
|
+
if (options.verbose && result.stdout) {
|
|
169
|
+
console.log('Output:', result.stdout);
|
|
170
|
+
}
|
|
171
|
+
} catch (error) {
|
|
172
|
+
console.error('ā Command failed:', error.message);
|
|
173
|
+
|
|
174
|
+
if (error instanceof GitHubCliTimeoutError) {
|
|
175
|
+
console.error('š” Try increasing timeout with --timeout <ms>');
|
|
176
|
+
} else if (error instanceof GitHubCliValidationError) {
|
|
177
|
+
console.error('š” Input validation failed. Check for dangerous characters or patterns.');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (options.verbose && error.details) {
|
|
181
|
+
console.error('Details:', error.details);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Handle issue commands
|
|
190
|
+
*/
|
|
191
|
+
async function handleIssueCommand(subcommand, positionalArgs, options, cliOptions) {
|
|
192
|
+
if (subcommand === 'create') {
|
|
193
|
+
if (!options.title || !options.body) {
|
|
194
|
+
throw new Error('Issue creation requires --title and --body options');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return await githubCli.createIssue({
|
|
198
|
+
title: options.title,
|
|
199
|
+
body: options.body,
|
|
200
|
+
labels: options.labels ? options.labels.split(',') : [],
|
|
201
|
+
assignees: options.assignees ? options.assignees.split(',') : [],
|
|
202
|
+
...cliOptions,
|
|
203
|
+
});
|
|
204
|
+
} else if (subcommand === 'comment') {
|
|
205
|
+
const [issueNumber] = positionalArgs;
|
|
206
|
+
const body = positionalArgs[1] || options.body;
|
|
207
|
+
|
|
208
|
+
if (!issueNumber || !body) {
|
|
209
|
+
throw new Error('Issue comment requires issue number and body');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return await githubCli.addIssueComment(parseInt(issueNumber), body, cliOptions);
|
|
213
|
+
} else {
|
|
214
|
+
throw new Error(`Unsupported issue subcommand: ${subcommand}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Handle PR commands
|
|
220
|
+
*/
|
|
221
|
+
async function handlePRCommand(subcommand, positionalArgs, options, cliOptions) {
|
|
222
|
+
if (subcommand === 'create') {
|
|
223
|
+
if (!options.title || !options.body) {
|
|
224
|
+
throw new Error('PR creation requires --title and --body options');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return await githubCli.createPR({
|
|
228
|
+
title: options.title,
|
|
229
|
+
body: options.body,
|
|
230
|
+
base: options.base || 'main',
|
|
231
|
+
head: options.head,
|
|
232
|
+
draft: options.draft || false,
|
|
233
|
+
...cliOptions,
|
|
234
|
+
});
|
|
235
|
+
} else if (subcommand === 'comment') {
|
|
236
|
+
const [prNumber] = positionalArgs;
|
|
237
|
+
const body = positionalArgs[1] || options.body;
|
|
238
|
+
|
|
239
|
+
if (!prNumber || !body) {
|
|
240
|
+
throw new Error('PR comment requires PR number and body');
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return await githubCli.addPRComment(parseInt(prNumber), body, cliOptions);
|
|
244
|
+
} else {
|
|
245
|
+
throw new Error(`Unsupported PR subcommand: ${subcommand}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Handle release commands
|
|
251
|
+
*/
|
|
252
|
+
async function handleReleaseCommand(subcommand, positionalArgs, options, cliOptions) {
|
|
253
|
+
if (subcommand === 'create') {
|
|
254
|
+
const [tag] = positionalArgs;
|
|
255
|
+
|
|
256
|
+
if (!tag || !options.title || !options.body) {
|
|
257
|
+
throw new Error('Release creation requires tag, --title, and --body');
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return await githubCli.createRelease({
|
|
261
|
+
tag,
|
|
262
|
+
title: options.title,
|
|
263
|
+
body: options.body,
|
|
264
|
+
prerelease: options.prerelease || false,
|
|
265
|
+
draft: options.draft || false,
|
|
266
|
+
...cliOptions,
|
|
267
|
+
});
|
|
268
|
+
} else {
|
|
269
|
+
throw new Error(`Unsupported release subcommand: ${subcommand}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Main execution
|
|
275
|
+
*/
|
|
276
|
+
async function main() {
|
|
277
|
+
try {
|
|
278
|
+
// Parse arguments
|
|
279
|
+
const { command, subcommand, positionalArgs, options } = parseArguments(args);
|
|
280
|
+
|
|
281
|
+
// Check GitHub CLI availability
|
|
282
|
+
const isAvailable = await githubCli.checkGitHubCli();
|
|
283
|
+
if (!isAvailable) {
|
|
284
|
+
console.error('ā GitHub CLI is not installed or not in PATH');
|
|
285
|
+
console.error('š” Install from: https://cli.github.com/');
|
|
286
|
+
process.exit(1);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Check authentication (unless dry-run)
|
|
290
|
+
if (!options['dry-run']) {
|
|
291
|
+
const isAuthenticated = await githubCli.checkAuthentication();
|
|
292
|
+
if (!isAuthenticated) {
|
|
293
|
+
console.error('ā GitHub CLI is not authenticated');
|
|
294
|
+
console.error('š” Run: gh auth login');
|
|
295
|
+
process.exit(1);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Execute command
|
|
300
|
+
await executeCommand(command, subcommand, positionalArgs, options);
|
|
301
|
+
} catch (error) {
|
|
302
|
+
console.error('ā Unexpected error:', error.message);
|
|
303
|
+
if (args.includes('--verbose')) {
|
|
304
|
+
console.error('Stack trace:', error.stack);
|
|
305
|
+
}
|
|
306
|
+
process.exit(1);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Handle process cleanup
|
|
311
|
+
process.on('SIGINT', async () => {
|
|
312
|
+
console.log('\nš Received interrupt signal, cleaning up...');
|
|
313
|
+
await githubCli.cleanup();
|
|
314
|
+
process.exit(0);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
process.on('SIGTERM', async () => {
|
|
318
|
+
console.log('\nš Received termination signal, cleaning up...');
|
|
319
|
+
await githubCli.cleanup();
|
|
320
|
+
process.exit(0);
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// Run if called directly
|
|
324
|
+
if (import.meta.main || process.argv[1].endsWith('github-safe-enhanced.js')) {
|
|
325
|
+
main().catch((error) => {
|
|
326
|
+
console.error('š„ Fatal error:', error.message);
|
|
327
|
+
process.exit(1);
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
export { executeCommand, handleIssueCommand, handlePRCommand, handleReleaseCommand };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Safe GitHub CLI Helper
|
|
5
|
+
* Prevents timeout issues when using gh commands with special characters
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ./github-safe.js issue comment 123 "Message with `backticks`"
|
|
9
|
+
* ./github-safe.js pr create --title "Title" --body "Complex body"
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { execSync } from 'child_process';
|
|
13
|
+
import { writeFileSync, unlinkSync } from 'fs';
|
|
14
|
+
import { tmpdir } from 'os';
|
|
15
|
+
import { join } from 'path';
|
|
16
|
+
import { randomBytes } from 'crypto';
|
|
17
|
+
|
|
18
|
+
const args = process.argv.slice(2);
|
|
19
|
+
|
|
20
|
+
if (args.length < 2) {
|
|
21
|
+
console.log(`
|
|
22
|
+
Safe GitHub CLI Helper
|
|
23
|
+
|
|
24
|
+
Usage:
|
|
25
|
+
./github-safe.js issue comment <number> <body>
|
|
26
|
+
./github-safe.js pr comment <number> <body>
|
|
27
|
+
./github-safe.js issue create --title <title> --body <body>
|
|
28
|
+
./github-safe.js pr create --title <title> --body <body>
|
|
29
|
+
|
|
30
|
+
This helper prevents timeout issues with special characters like:
|
|
31
|
+
- Backticks in code examples
|
|
32
|
+
- Command substitution \$(...)
|
|
33
|
+
- Directory paths
|
|
34
|
+
- Special shell characters
|
|
35
|
+
`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const [command, subcommand, ...restArgs] = args;
|
|
40
|
+
|
|
41
|
+
// Handle commands that need body content
|
|
42
|
+
if (
|
|
43
|
+
(command === 'issue' || command === 'pr') &&
|
|
44
|
+
(subcommand === 'comment' || subcommand === 'create')
|
|
45
|
+
) {
|
|
46
|
+
let bodyIndex = -1;
|
|
47
|
+
let body = '';
|
|
48
|
+
|
|
49
|
+
if (subcommand === 'comment' && restArgs.length >= 2) {
|
|
50
|
+
// Simple format: github-safe.js issue comment 123 "body"
|
|
51
|
+
body = restArgs[1];
|
|
52
|
+
bodyIndex = 1;
|
|
53
|
+
} else {
|
|
54
|
+
// Flag format: --body "content"
|
|
55
|
+
bodyIndex = restArgs.indexOf('--body');
|
|
56
|
+
if (bodyIndex !== -1 && bodyIndex < restArgs.length - 1) {
|
|
57
|
+
body = restArgs[bodyIndex + 1];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (body) {
|
|
62
|
+
// Use temporary file for body content
|
|
63
|
+
const tmpFile = join(tmpdir(), `gh-body-${randomBytes(8).toString('hex')}.tmp`);
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
writeFileSync(tmpFile, body, 'utf8');
|
|
67
|
+
|
|
68
|
+
// Build new command with --body-file
|
|
69
|
+
const newArgs = [...restArgs];
|
|
70
|
+
if (subcommand === 'comment' && bodyIndex === 1) {
|
|
71
|
+
// Replace body with --body-file
|
|
72
|
+
newArgs[1] = '--body-file';
|
|
73
|
+
newArgs.push(tmpFile);
|
|
74
|
+
} else if (bodyIndex !== -1) {
|
|
75
|
+
// Replace --body with --body-file
|
|
76
|
+
newArgs[bodyIndex] = '--body-file';
|
|
77
|
+
newArgs[bodyIndex + 1] = tmpFile;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Execute safely
|
|
81
|
+
const ghCommand = `gh ${command} ${subcommand} ${newArgs.join(' ')}`;
|
|
82
|
+
console.log(`Executing: ${ghCommand}`);
|
|
83
|
+
|
|
84
|
+
const result = execSync(ghCommand, {
|
|
85
|
+
stdio: 'inherit',
|
|
86
|
+
timeout: 30000, // 30 second timeout
|
|
87
|
+
});
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error('Error:', error.message);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
} finally {
|
|
92
|
+
// Clean up
|
|
93
|
+
try {
|
|
94
|
+
unlinkSync(tmpFile);
|
|
95
|
+
} catch (e) {
|
|
96
|
+
// Ignore cleanup errors
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
// No body content, execute normally
|
|
101
|
+
execSync(`gh ${args.join(' ')}`, { stdio: 'inherit' });
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
// Other commands, execute normally
|
|
105
|
+
execSync(`gh ${args.join(' ')}`, { stdio: 'inherit' });
|
|
106
|
+
}
|