goodcommit 0.2.1

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/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # goodcommit (npm)
2
+
3
+ Install the `goodcommit` binary from GitHub Releases via npm.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g goodcommit
9
+ ```
10
+
11
+ Commands installed:
12
+ - `goodcommit`
13
+ - `g`
14
+
15
+ For `g.` (dot) alias, use the curl installer or Homebrew.
16
+
17
+ ## Setup
18
+
19
+ ```bash
20
+ goodcommit setup
21
+ ```
22
+
23
+ Setup asks for your provider, push defaults, and (if OpenAI) your API key.
24
+ You can also set `OPENAI_API_KEY` instead of storing it in config.
package/bin/g ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require('path');
4
+ const { spawnSync } = require('child_process');
5
+
6
+ const binary = path.join(__dirname, 'native', 'goodcommit');
7
+
8
+ const result = spawnSync(binary, process.argv.slice(2), { stdio: 'inherit' });
9
+ if (result.error) {
10
+ console.error('error: goodcommit binary not found. Reinstall the package.');
11
+ process.exit(1);
12
+ }
13
+
14
+ process.exit(result.status ?? 1);
package/bin/goodcommit ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require('path');
4
+ const { spawnSync } = require('child_process');
5
+
6
+ const binary = path.join(__dirname, 'native', 'goodcommit');
7
+
8
+ const result = spawnSync(binary, process.argv.slice(2), { stdio: 'inherit' });
9
+ if (result.error) {
10
+ console.error('error: goodcommit binary not found. Reinstall the package.');
11
+ process.exit(1);
12
+ }
13
+
14
+ process.exit(result.status ?? 1);
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "goodcommit",
3
+ "version": "0.2.1",
4
+ "description": "Good Commit: fast, reliable AI commit messages",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/Bikz/goodcommit"
9
+ },
10
+ "homepage": "https://github.com/Bikz/goodcommit",
11
+ "keywords": [
12
+ "git",
13
+ "commit",
14
+ "ai",
15
+ "cli",
16
+ "conventional-commits",
17
+ "commit-message",
18
+ "openai",
19
+ "ollama",
20
+ "gpt-5",
21
+ "opencommit",
22
+ "git-ai-commit",
23
+ "goodcommit",
24
+ "good-commit"
25
+ ],
26
+ "bin": {
27
+ "goodcommit": "bin/goodcommit",
28
+ "g": "bin/g"
29
+ },
30
+ "os": ["darwin", "linux"],
31
+ "cpu": ["x64", "arm64"],
32
+ "scripts": {
33
+ "postinstall": "node scripts/install.js"
34
+ }
35
+ }
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const https = require('https');
6
+ const { execFileSync } = require('child_process');
7
+
8
+ const REPO = 'Bikz/goodcommit';
9
+ const BIN_NAME = 'goodcommit';
10
+
11
+ function fail(message) {
12
+ console.error(`error: ${message}`);
13
+ process.exit(1);
14
+ }
15
+
16
+ function resolveTarget() {
17
+ const platform = process.platform;
18
+ const arch = process.arch;
19
+
20
+ const archMap = {
21
+ x64: 'x86_64',
22
+ arm64: 'aarch64'
23
+ };
24
+
25
+ const osMap = {
26
+ darwin: 'apple-darwin',
27
+ linux: 'unknown-linux-gnu'
28
+ };
29
+
30
+ if (!archMap[arch]) {
31
+ fail(`unsupported architecture: ${arch}`);
32
+ }
33
+
34
+ if (!osMap[platform]) {
35
+ fail(`unsupported platform: ${platform}`);
36
+ }
37
+
38
+ return `${archMap[arch]}-${osMap[platform]}`;
39
+ }
40
+
41
+ function download(url, dest) {
42
+ return new Promise((resolve, reject) => {
43
+ const file = fs.createWriteStream(dest);
44
+ https.get(url, (response) => {
45
+ if (response.statusCode !== 200) {
46
+ reject(new Error(`status:${response.statusCode}`));
47
+ return;
48
+ }
49
+
50
+ response.pipe(file);
51
+ file.on('finish', () => file.close(resolve));
52
+ }).on('error', (err) => {
53
+ fs.unlink(dest, () => reject(err));
54
+ });
55
+ });
56
+ }
57
+
58
+ async function install() {
59
+ const target = resolveTarget();
60
+ if (target === 'aarch64-unknown-linux-gnu') {
61
+ fail('linux arm64 builds are not yet available');
62
+ }
63
+ const asset = `${BIN_NAME}-${target}.tar.gz`;
64
+ const url = `https://github.com/${REPO}/releases/latest/download/${asset}`;
65
+
66
+ const packageRoot = path.join(__dirname, '..');
67
+ const binDir = path.join(packageRoot, 'bin');
68
+ const nativeDir = path.join(binDir, 'native');
69
+ const archivePath = path.join(binDir, asset);
70
+ const binaryPath = path.join(nativeDir, BIN_NAME);
71
+
72
+ fs.mkdirSync(nativeDir, { recursive: true });
73
+
74
+ if (fs.existsSync(binaryPath)) {
75
+ return;
76
+ }
77
+
78
+ console.log(`Downloading ${url}`);
79
+ try {
80
+ await download(url, archivePath);
81
+ } catch (err) {
82
+ if (String(err.message || err).includes('status:404')) {
83
+ fail(
84
+ `no prebuilt binary for ${target}. Build from source: cargo build --release`
85
+ );
86
+ }
87
+ throw err;
88
+ }
89
+
90
+ try {
91
+ execFileSync('tar', ['-xzf', archivePath, '-C', nativeDir], { stdio: 'inherit' });
92
+ } catch (err) {
93
+ fail('failed to extract archive (tar required)');
94
+ }
95
+
96
+ fs.unlinkSync(archivePath);
97
+ fs.chmodSync(binaryPath, 0o755);
98
+ }
99
+
100
+ install().catch((err) => fail(err.message));