diff --git a/package-lock.json b/package-lock.json index f32c360..3738861 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gitbun", - "version": "1.2.4", + "version": "1.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "gitbun", - "version": "1.2.4", + "version": "1.3.0", "license": "MIT", "dependencies": { "chalk": "^5.6.2", @@ -1440,7 +1440,6 @@ "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.3", @@ -2513,7 +2512,6 @@ "integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -2570,7 +2568,6 @@ "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/types": "8.56.1", @@ -2873,7 +2870,6 @@ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3555,7 +3551,6 @@ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "license": "MIT", - "peer": true, "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", @@ -4003,7 +3998,6 @@ "integrity": "sha512-uYixubwmqJZH+KLVYIVKY1JQt7tysXhtj21WSvjcSmU5SVNzMus1bgLe+pAt816yQ8opKfheVVoPLqvVMGejYw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", @@ -5411,7 +5405,6 @@ "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", "dev": true, "license": "MIT", - "peer": true, "bin": { "marked": "bin/marked.js" }, @@ -7592,7 +7585,6 @@ "dev": true, "inBundle": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -8033,7 +8025,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -8557,7 +8548,6 @@ "integrity": "sha512-WRgl5GcypwramYX4HV+eQGzUbD7UUbljVmS+5G1uMwX/wLgYuJAxGeerXJDMO2xshng4+FXqCgyB5QfClV6WjA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/error": "^4.0.0", @@ -9680,7 +9670,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -9851,7 +9840,6 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", diff --git a/src/index.ts b/src/index.ts index 8d80d31..e3828e8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -55,66 +55,83 @@ export async function run(options: CliOptions) { process.exit(0); } - // Enrich file stats - const enrichedFiles: FileChange[] = []; - - for (const file of stagedFiles) { - const stats = await getDiffStats(file.path); - enrichedFiles.push({ - path: file.path, - additions: stats.additions, - deletions: stats.deletions, - status: file.status - }); - } - -const filteredFiles = filterLowSignalFiles(enrichedFiles); -const prioritizedCandidates = sortBySignal(filteredFiles, getDiffForFile); -const prioritizedFiles = prioritizedCandidates.length > 0 - ? prioritizedCandidates - : enrichedFiles; -const MIN_GROUP_SIZE = 2; -const deduplicatedResult = deduplicateFiles(prioritizedFiles, MIN_GROUP_SIZE); - -const scope = detectScope(prioritizedFiles.map(f => f.path)); -const type = await classifyCommitType(prioritizedFiles); -const summary = generateSummaryFromResult(deduplicatedResult); - - -// Load config -const config = await loadConfig(); - -let commitMessage = generateCommitMessage(type, scope, prioritizedFiles, config.format); - + const spinner = ora(); + let commitMessage = ""; - // AI enhancement (optional) - if (options.ai) { - const running = await isOllamaRunning(); - - if (!running) { - console.log( - chalk.yellow("Ollama is not running. Using rule-based commit.") - ); - } else { - let selectedModel = options.model || config.model; - - if (!selectedModel) { - selectedModel = (await getBestModel()) || "deepseek-coder:6.7b"; - } - - const spinner = ora(`Enhancing commit with AI (${selectedModel})...`).start(); + try { + const enrichedFiles: FileChange[] = []; + spinner.start("Analyzing staged changes..."); + for (const file of stagedFiles) { + const stats = await getDiffStats(file.path); + enrichedFiles.push({ + path: file.path, + additions: stats.additions, + deletions: stats.deletions, + status: file.status, + }); + } - try { - commitMessage = await enhanceCommit( - commitMessage, - summary, - selectedModel + const filteredFiles = filterLowSignalFiles(enrichedFiles); + const prioritizedCandidates = sortBySignal(filteredFiles, getDiffForFile); + const prioritizedFiles = + prioritizedCandidates.length > 0 ? prioritizedCandidates : enrichedFiles; + const MIN_GROUP_SIZE = 2; + const deduplicatedResult = deduplicateFiles( + prioritizedFiles, + MIN_GROUP_SIZE + ); + + const scope = detectScope(prioritizedFiles.map((f) => f.path)); + const type = await classifyCommitType(prioritizedFiles); + const summary = generateSummaryFromResult(deduplicatedResult); + + spinner.succeed("Analyzing staged changes..."); + + // Load config + const config = await loadConfig(); + + spinner.start("Generating commit message..."); + commitMessage = generateCommitMessage( + type, + scope, + prioritizedFiles, + config.format + ); + spinner.succeed("Generating commit message..."); + + // AI enhancement (optional) + if (options.ai) { + const running = await isOllamaRunning(); + + if (!running) { + console.log( + chalk.yellow("\nOllama is not running. Using rule-based commit.") ); - spinner.succeed(); - } catch { - spinner.fail("AI enhancement failed"); + } else { + let selectedModel = options.model || config.model; + + if (!selectedModel) { + selectedModel = (await getBestModel()) || "deepseek-coder:6.7b"; + } + + spinner.start(`Enhancing commit with AI (${selectedModel})...`); + + try { + commitMessage = await enhanceCommit( + commitMessage, + summary, + selectedModel + ); + spinner.succeed(`Enhanced commit with AI (${selectedModel})`); + } catch { + spinner.fail("AI enhancement failed"); + } } } + } catch (error) { + spinner.fail("Failed during analysis or generation."); + console.error(error); + process.exit(1); } // Confirmation flow