-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Problem
The project follows many Node.js CLI best practices but is missing some standard conventions that improve user experience and compatibility.
Based on nodejs-cli-apps-best-practices and 2025 Node.js standards.
Missing Best Practices
1. No Top-Level --version Flag
Current: Version only shown via git gpt config subcommand
Expected: Standard -v, --version flag
# Current - not working
$ git gpt --version
# Invalid command
# Expected behavior
$ git gpt --version
0.10.2
$ git gpt -v
0.10.2Implementation:
import { readFileSync } from 'fs'
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
const packageJson = JSON.parse(
readFileSync(join(__dirname, 'package.json'), 'utf8')
)
program
.name('git-gpt')
.description('AI-powered Git commit message generator')
.version(packageJson.version, '-v, --version', 'Output the version number')
.helpOption('-h, --help', 'Display help for command')2. No Node.js Version Enforcement
Current: Volta specifies v22.18.0, but no package.json enforcement
Risk: Users on old Node.js versions may encounter runtime errors
Add to package.json:
{
"engines": {
"node": ">=18.0.0"
}
}Why Node 18+:
- Native ES Modules support (required by project)
- Stable fetch API
- Updated OpenAI SDK requirements
- Long-term support (LTS)
3. Missing .editorconfig
Current: Only .prettierrc for formatting
Issue: Different editors may use different settings
Create .editorconfig:
# EditorConfig: https://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.{js,json,md,yml,yaml}]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false
[package.json]
indent_size = 24. API Key Format Validation
Current: No validation of OpenAI API key format
Issue: Cryptic errors when invalid key is used
/**
* Validates OpenAI API key format
* @param {string} key - API key to validate
* @returns {boolean} True if valid format
*/
function isValidOpenAIKey(key) {
// OpenAI keys start with 'sk-' or 'sk-proj-'
// Followed by alphanumeric characters
return /^sk-[a-zA-Z0-9-_]{20,}$/.test(key)
}
// In open-api-key command
if (response.value) {
if (!isValidOpenAIKey(response.value)) {
console.error('❌ Invalid API key format.')
console.error(' OpenAI keys should start with "sk-"')
console.error(' Get your key at: https://platform.openai.com/api-keys')
return
}
saveConfig({ apiKey: response.value })
apiKey = response.value
console.log('✅ API key saved to configuration.')
}5. Environment Variable Validation
Current: Silent fallback to .env if config key missing
Better: Validate and provide clear guidance
/**
* Gets OpenAI API key with validation and helpful errors
* @returns {string} Valid API key
* @throws {Error} If no key found or invalid format
*/
function getValidatedApiKey() {
// Priority: config file > .env file
const key = apiKey || process.env.OPENAI_API_KEY
if (!key) {
console.error('❌ No OpenAI API key found.')
console.error('\nOptions:')
console.error(' 1. Set via command: git gpt open-api-key add')
console.error(' 2. Set in .env file: OPENAI_API_KEY=sk-...')
console.error('\nGet your key at: https://platform.openai.com/api-keys')
process.exit(1)
}
if (!isValidOpenAIKey(key)) {
console.error('❌ Invalid OpenAI API key format.')
console.error(' Keys should start with "sk-"')
console.error('\nUpdate your key: git gpt open-api-key add')
process.exit(1)
}
return key
}6. Exit Code Standardization
Current: All errors exit with code 1
Better: Use standard exit codes
const EXIT_CODES = {
SUCCESS: 0,
GENERAL_ERROR: 1,
INVALID_USAGE: 2,
CONFIG_ERROR: 3,
API_ERROR: 4,
NETWORK_ERROR: 5,
GIT_ERROR: 6,
}
// Usage
if (!gitDiff) {
console.log('No changes to commit.')
process.exit(EXIT_CODES.SUCCESS) // Not an error
}
if (error.status === 401) {
console.error('Invalid API key')
process.exit(EXIT_CODES.API_ERROR)
}7. Signal Handling (Graceful Shutdown)
Current: No cleanup on SIGINT/SIGTERM
Better: Handle signals gracefully
// Graceful shutdown
process.on('SIGINT', () => {
console.log('\n\n👋 Commit canceled by user.')
process.exit(EXIT_CODES.SUCCESS)
})
process.on('SIGTERM', () => {
console.log('\n\n👋 Process terminated.')
process.exit(EXIT_CODES.SUCCESS)
})
// Cleanup on exit
process.on('exit', (code) => {
// Cleanup temporary files if any
// Close file handles if any
})Implementation Checklist
High Priority
- Add
--version/-vtop-level flag - Add
enginesfield to package.json - Add API key format validation
- Improve environment variable error messages
Medium Priority
- Create
.editorconfigfile - Standardize exit codes
- Add signal handling (SIGINT, SIGTERM)
Low Priority
- Add
--helpcustomization for each command - Consider adding
--quiet/-qflag for scripting - Consider adding
--dry-runflag to preview message
Benefits
- ✅ Better user experience
- ✅ Standard CLI conventions
- ✅ Cross-platform compatibility
- ✅ Better error messages
- ✅ Easier debugging
Acceptance Criteria
-
git gpt --versionworks -
git gpt -vworks - Node.js version checked on install
- API key format validated on save
-
.editorconfigcreated - Exit codes standardized
- Signal handling implemented
- Tests updated for new behavior
- Documentation updated
Priority
Low-Medium - Nice to have, improves polish
Related
Quality analysis report: claudedocs/quality-analysis-report.md section 6