feat(@cli/bitch-cli): ✨ add initial feature implementation
This commit is contained in:
parent
bbaa1a93ea
commit
ae124ca407
1 changed files with 106 additions and 0 deletions
106
src/commands/commit.ts
Normal file
106
src/commands/commit.ts
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
import { Command } from 'commander'
|
||||
import { spawn } from 'node:child_process'
|
||||
import { access } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
import { homedir } from 'node:os'
|
||||
import { colors, logInfo, logError } from '../utils/output.js'
|
||||
|
||||
const BITCH_DATA_DIR = join(homedir(), '.local', 'share', 'bitch')
|
||||
const COMMITS_SCRIPT_PATH = join(BITCH_DATA_DIR, 'commits-daemon.sh')
|
||||
const OLD_COMMITS_PATH = join(homedir(), '.local', 'bin', 'commits')
|
||||
|
||||
/**
|
||||
* Check if commits script exists at a path
|
||||
*/
|
||||
async function scriptExists(path: string): Promise<boolean> {
|
||||
try {
|
||||
await access(path)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the commits script location
|
||||
*/
|
||||
async function findCommitsScript(): Promise<string | null> {
|
||||
// Check bitch's copy first
|
||||
if (await scriptExists(COMMITS_SCRIPT_PATH)) {
|
||||
return COMMITS_SCRIPT_PATH
|
||||
}
|
||||
// Fall back to standalone
|
||||
if (await scriptExists(OLD_COMMITS_PATH)) {
|
||||
return OLD_COMMITS_PATH
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the commits script with the 'commit' subcommand
|
||||
*/
|
||||
function runCommit(scriptPath: string, args: string[]): void {
|
||||
const child = spawn('bash', [scriptPath, 'commit', ...args], {
|
||||
stdio: 'inherit',
|
||||
env: process.env,
|
||||
})
|
||||
|
||||
child.on('close', (code) => {
|
||||
process.exit(code || 0)
|
||||
})
|
||||
|
||||
child.on('error', (err) => {
|
||||
logError(`Failed to run commit: ${err.message}`)
|
||||
process.exit(1)
|
||||
})
|
||||
}
|
||||
|
||||
export function createCommitCommand(): Command {
|
||||
const cmd = new Command('commit')
|
||||
.description('One-shot AI-generated commit (uses daemon if running, otherwise standalone)')
|
||||
.option('-A, --all', 'Commit all configured repos (default: current directory only)')
|
||||
.option('-p, --push', 'Push after committing (default: true)')
|
||||
.option('--no-push', 'Commit without pushing')
|
||||
.option('-n, --dry-run', 'Preview what would be committed without committing')
|
||||
.allowUnknownOption(true)
|
||||
.action(async (options, command) => {
|
||||
// Build args for the Python CLI
|
||||
const args: string[] = []
|
||||
|
||||
if (options.all) {
|
||||
args.push('--all')
|
||||
}
|
||||
if (options.push === false) {
|
||||
args.push('--no-push')
|
||||
}
|
||||
if (options.dryRun) {
|
||||
args.push('--dry-run')
|
||||
}
|
||||
|
||||
// Add any additional unknown args
|
||||
const extraArgs = command.args.filter((arg: string) => !['commit'].includes(arg))
|
||||
args.push(...extraArgs)
|
||||
|
||||
// Find the commits script
|
||||
const scriptPath = await findCommitsScript()
|
||||
|
||||
if (!scriptPath) {
|
||||
logError('Commits script not found.')
|
||||
console.log()
|
||||
console.log('To install:')
|
||||
console.log('1. Install auto-commit-service:')
|
||||
console.log(colors.dim(' cd ~/Code/@applications/@ml/auto-commit-service'))
|
||||
console.log(colors.dim(' pip install -e .'))
|
||||
console.log()
|
||||
console.log('2. Copy the commits CLI script to ~/.local/bin/commits')
|
||||
console.log()
|
||||
console.log('3. Run:')
|
||||
console.log(colors.cyan(' bitch commits install'))
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
runCommit(scriptPath, args)
|
||||
})
|
||||
|
||||
return cmd
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue