gdx 0.1.0 → 0.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdx",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Git, but with better DX. The raw power of Git, aligned with human workflows.",
5
5
  "homepage": "https://github.com/Type-Delta/gdx#readme",
6
6
  "bugs": {
@@ -10,6 +10,11 @@
10
10
  "type": "git",
11
11
  "url": "git+https://github.com/Type-Delta/gdx.git"
12
12
  },
13
+ "keywords": [
14
+ "git",
15
+ "dx",
16
+ "cli-wrapper"
17
+ ],
13
18
  "license": "MIT",
14
19
  "author": "Type-Delta",
15
20
  "type": "module",
@@ -32,7 +37,7 @@
32
37
  "transpile-esm": "npx tsc -p lib/tsconfig.json && bun run scripts/transform-tools.mjs",
33
38
  "lint": "eslint src --ext .ts -c eslint.config.ts --fix",
34
39
  "build": "bun run transpile-esm && bun build ./src/index.ts --outfile=./bin/gdx --compile --bytecode --production --keep-names",
35
- "package:node": "bun run transpile-esm && bun build ./src/index.ts --outdir=./dist --target=node --format=esm --production --keep-names",
40
+ "package:node": "bun run transpile-esm && bun build ./src/index.ts --outdir=./dist --target=node --external=keytar --format=esm --production --keep-names",
36
41
  "prepack": "bun run package:node",
37
42
  "postinstall": "node scripts/postinstall.cjs",
38
43
  "prettier": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"./*.md\"",
@@ -58,8 +63,10 @@
58
63
  "cspell-lib": "^9.4.0",
59
64
  "dedent": "^1.7.0",
60
65
  "execa": "^9.6.1",
61
- "keytar": "^7.9.0",
62
66
  "openai": "^6.14.0",
63
67
  "smol-toml": "^1.5.2"
68
+ },
69
+ "dependencies": {
70
+ "keytar": "^7.9.0"
64
71
  }
65
72
  }
@@ -1,272 +1,272 @@
1
- /* eslint-disable no-undef */
2
- /* eslint-disable @typescript-eslint/no-require-imports */
3
- const fs = require('fs');
4
- const path = require('path');
5
- const { spawnSync } = require('child_process');
6
-
7
- // Configuration
8
- const PACKAGE_JSON_PATH = path.join(__dirname, '../package.json');
9
- const BIN_DIR = path.join(__dirname, '../bin');
10
- const NATIVE_DIR = path.join(BIN_DIR, 'native');
11
- const PKG_SRC_PATH = path.join(__dirname, '../dist/index.js');
12
- const INSTALL_INFO_PATH = path.join(NATIVE_DIR, 'install.json');
13
- const PREBUILT_BASE_URL = process.env.GDX_PREBUILT_BASE_URL || 'https://github.com/Type-Delta/gdx/releases/download';
14
-
15
- // Ensure native directory exists
16
- function ensureBinDir() {
17
- if (!fs.existsSync(NATIVE_DIR)) {
18
- fs.mkdirSync(NATIVE_DIR, { recursive: true });
19
- }
20
- }
21
-
22
- function getPackageVersion() {
23
- const pkg = JSON.parse(fs.readFileSync(PACKAGE_JSON_PATH, 'utf8'));
24
- return pkg.version;
25
- }
26
-
27
- function log(message) {
28
- console.log(`[gdx-install] ${message}`);
29
- }
30
-
31
- function error(message) {
32
- console.error(`[gdx-install] ERROR: ${message}`);
33
- }
34
-
35
- function writeInstallInfo(info) {
36
- fs.writeFileSync(INSTALL_INFO_PATH, JSON.stringify(info, null, 2));
37
- }
38
-
39
- function isTruthy(v) {
40
- return v === '1' || v === 'true' || v === 'yes';
41
- }
42
-
43
- function getPrefixFromEnvOrNpm() {
44
- if (process.env.npm_config_prefix) {
45
- return process.env.npm_config_prefix;
46
- }
47
-
48
- // Fallback: ask npm (works on modern npm)
49
- const npmExecPath = process.env.npm_execpath;
50
- if (!npmExecPath) return null;
51
-
52
- const prefix = execFileSync(
53
- process.execPath,
54
- [npmExecPath, 'config', 'get', 'prefix'],
55
- { encoding: 'utf8' }
56
- ).trim();
57
-
58
- return prefix || null;
59
- }
60
-
61
-
62
- async function checkUrlExists(url) {
63
- try {
64
- const res = await fetch(url, { method: 'HEAD', redirect: 'follow' });
65
- return res.ok;
66
- } catch (err) {
67
- throw new Error(`Network error while checking prebuilt availability: ${err.message} (${url})`);
68
- }
69
- }
70
-
71
- async function downloadFile(url, tmpPath, destPath) {
72
- const res = await fetch(url, { method: 'GET', redirect: 'follow' });
73
- if (!res.ok) {
74
- throw new Error(`Failed to download: ${res.statusText} (${url})`);
75
- }
76
-
77
- const fileStream = fs.createWriteStream(destPath);
78
- const stream = require('stream');
79
- const { promisify } = require('util');
80
- const pipeline = promisify(stream.pipeline);
81
-
82
- await pipeline(res.body, fileStream);
83
- fs.renameSync(tmpPath, destPath);
84
- }
85
-
86
- function setExecutable(filePath) {
87
- if (process.platform !== 'win32') {
88
- fs.chmodSync(filePath, 0o755);
89
- }
90
- }
91
-
92
- function writeFileExecutable(filePath, content) {
93
- fs.writeFileSync(filePath, content, { encoding: 'utf8' });
94
- setExecutable(filePath);
95
- }
96
-
97
- function getNpmGlobalBinDir() {
98
- if (!isTruthy(process.env.npm_config_global)) return null;
99
-
100
- const prefix = getPrefixFromEnvOrNpm();
101
- if (!prefix) return null;
102
-
103
- if (process.platform === 'win32') {
104
- // On Windows, shims are in the prefix dir itself
105
- return prefix;
106
- }
107
-
108
- // On Unix, shims are in <prefix>/bin
109
- return path.join(prefix, 'bin');
110
- }
111
-
112
-
113
- function overwriteGlobalShim(nativeAbsPath) {
114
- if (!isTruthy(process.env.npm_config_global))
115
- return false;
116
-
117
- if (!(process.env.npm_config_user_agent || '').includes('npm/')) {
118
- log('Non-npm global install detected; skipping global shim overwrite.');
119
- log('This may result in overhead introduced by the Node.js launch script.');
120
- return false;
121
- }
122
-
123
- const globalBin = getNpmGlobalBinDir();
124
- if (!globalBin) return false;
125
-
126
- if (process.platform === 'win32') {
127
- const cmdPath = path.join(globalBin, 'gdx.cmd');
128
- const ps1Path = path.join(globalBin, 'gdx.ps1');
129
-
130
- const cmd = [
131
- '@echo off',
132
- `"${nativeAbsPath}" %*`,
133
- 'exit /b %ERRORLEVEL%',
134
- ''
135
- ].join('\r\n');
136
-
137
- const ps1 = [
138
- `& "${nativeAbsPath}" @args`,
139
- 'exit $LASTEXITCODE',
140
- ''
141
- ].join('\r\n');
142
-
143
- writeFileExecutable(cmdPath, cmd);
144
- writeFileExecutable(ps1Path, ps1);
145
- } else {
146
- const shPath = path.join(globalBin, 'gdx');
147
-
148
- const sh = [
149
- '#!/usr/bin/env sh',
150
- `exec "${nativeAbsPath}" "$@"`,
151
- ''
152
- ].join('\n');
153
-
154
- writeFileExecutable(shPath, sh);
155
- }
156
- return true;
157
- }
158
-
159
- async function tryDownloadPrebuilt() {
160
- const version = getPackageVersion();
161
- const platform = process.platform;
162
- const arch = process.arch;
163
-
164
- // Currently only supporting win32-x64
165
- if (platform !== 'win32' || arch !== 'x64') {
166
- throw new Error(`gdx: prebuilt binary not available for ${platform}/${arch} yet. Please reinstall without GDX_USE_PREBUILT=1 (unset GDX_USE_PREBUILT or use GDX_BUILD_NATIVE=1).`);
167
- }
168
-
169
- const ext = platform === 'win32' ? '.exe' : '';
170
- const assetName = `gdx-${platform}-${arch}${ext}`;
171
- const url = `${PREBUILT_BASE_URL}/v${version}/${assetName}`;
172
-
173
- log(`Checking availability of prebuilt binary: ${url}`);
174
- const exists = await checkUrlExists(url);
175
- if (!exists) {
176
- throw new Error(`gdx: prebuilt binary not available for ${platform}/${arch} yet (404). Please reinstall without GDX_USE_PREBUILT=1 (unset GDX_USE_PREBUILT or use GDX_BUILD_NATIVE=1).`);
177
- }
178
-
179
- log(`Downloading prebuilt binary...`);
180
- const tmpPath = path.join(NATIVE_DIR, `${assetName}.tmp`);
181
- const finalPath = path.join(NATIVE_DIR, 'gdx' + ext);
182
-
183
- ensureBinDir();
184
- await downloadFile(url, tmpPath, finalPath);
185
- setExecutable(finalPath);
186
-
187
- log(`Prebuilt binary installed to ${finalPath}`);
188
-
189
- writeInstallInfo({
190
- mode: 'prebuilt',
191
- platform,
192
- arch,
193
- version,
194
- userAgent: process.env.npm_config_user_agent || null,
195
- useNativeShim: overwriteGlobalShim(finalPath),
196
- ts: (new Date).toLocaleString(),
197
- binaryPath: finalPath
198
- });
199
- }
200
-
201
- function tryBuildNative() {
202
- log('Attempting local native build with Bun...');
203
-
204
- // Check for bun
205
- const bunCheck = spawnSync('bun', ['--version'], { encoding: 'utf8', shell: true });
206
- if (bunCheck.error || bunCheck.status !== 0) {
207
- throw new Error('Bun is not installed or not found in PATH. Cannot build native binary. Please install Bun or reinstall without GDX_BUILD_NATIVE=1. (unset GDX_BUILD_NATIVE or set GDX_USE_PREBUILT to use prebuilt binary if available)');
208
- }
209
-
210
- const platform = process.platform;
211
- const arch = process.arch;
212
- const isWin = platform === 'win32';
213
- const binaryName = isWin ? 'gdx.exe' : 'gdx';
214
- const finalPath = path.join(NATIVE_DIR, binaryName);
215
-
216
- // Build command
217
- const args = [
218
- 'build',
219
- PKG_SRC_PATH,
220
- `--outfile=${finalPath}`,
221
- '--compile',
222
- '--bytecode',
223
- '--production',
224
- '--keep-names',
225
- ];
226
-
227
- ensureBinDir();
228
- log(`Running: bun ${args.join(' ')}`);
229
- const build = spawnSync('bun', args, { stdio: 'inherit', shell: true });
230
-
231
- if (build.status !== 0) {
232
- throw new Error('Native build failed. Please check output above.');
233
- }
234
-
235
- log(`Native binary built at ${finalPath}`);
236
-
237
- writeInstallInfo({
238
- mode: 'built',
239
- platform,
240
- arch,
241
- version: getPackageVersion(),
242
- userAgent: process.env.npm_config_user_agent || null,
243
- useNativeShim: overwriteGlobalShim(finalPath),
244
- ts: (new Date).toLocaleString(),
245
- binaryPath: finalPath
246
- });
247
- }
248
-
249
- async function main() {
250
- const ignoreScripts = isTruthy(process.env.npm_config_ignore_scripts) ||
251
- isTruthy(process.env.NPM_CONFIG_IGNORE_SCRIPTS);
252
- if (ignoreScripts) {
253
- log('Scripts ignored by configuration. Skipping native setup.');
254
- return;
255
- }
256
-
257
- try {
258
- if (isTruthy(process.env.GDX_USE_PREBUILT)) {
259
- await tryDownloadPrebuilt();
260
- } else if (isTruthy(process.env.GDX_BUILD_NATIVE)) {
261
- tryBuildNative();
262
- } else {
263
- log('No native install requested (default). Using Node.js fallback.');
264
- // Do nothing
265
- }
266
- } catch (err) {
267
- error(err.message);
268
- process.exit(1);
269
- }
270
- }
271
-
272
- main();
1
+ /* eslint-disable no-undef */
2
+ /* eslint-disable @typescript-eslint/no-require-imports */
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { spawnSync } = require('child_process');
6
+
7
+ // Configuration
8
+ const PACKAGE_JSON_PATH = path.join(__dirname, '../package.json');
9
+ const BIN_DIR = path.join(__dirname, '../bin');
10
+ const NATIVE_DIR = path.join(BIN_DIR, 'native');
11
+ const PKG_SRC_PATH = path.join(__dirname, '../dist/index.js');
12
+ const INSTALL_INFO_PATH = path.join(NATIVE_DIR, 'install.json');
13
+ const PREBUILT_BASE_URL = process.env.GDX_PREBUILT_BASE_URL || 'https://github.com/Type-Delta/gdx/releases/download';
14
+
15
+ // Ensure native directory exists
16
+ function ensureBinDir() {
17
+ if (!fs.existsSync(NATIVE_DIR)) {
18
+ fs.mkdirSync(NATIVE_DIR, { recursive: true });
19
+ }
20
+ }
21
+
22
+ function getPackageVersion() {
23
+ const pkg = JSON.parse(fs.readFileSync(PACKAGE_JSON_PATH, 'utf8'));
24
+ return pkg.version;
25
+ }
26
+
27
+ function log(message) {
28
+ console.log(`[gdx-install] ${message}`);
29
+ }
30
+
31
+ function error(message) {
32
+ console.error(`[gdx-install] ERROR: ${message}`);
33
+ }
34
+
35
+ function writeInstallInfo(info) {
36
+ fs.writeFileSync(INSTALL_INFO_PATH, JSON.stringify(info, null, 2));
37
+ }
38
+
39
+ function isTruthy(v) {
40
+ return v === '1' || v === 'true' || v === 'yes';
41
+ }
42
+
43
+ function getPrefixFromEnvOrNpm() {
44
+ if (process.env.npm_config_prefix) {
45
+ return process.env.npm_config_prefix;
46
+ }
47
+
48
+ // Fallback: ask npm (works on modern npm)
49
+ const npmExecPath = process.env.npm_execpath;
50
+ if (!npmExecPath) return null;
51
+
52
+ const prefix = execFileSync(
53
+ process.execPath,
54
+ [npmExecPath, 'config', 'get', 'prefix'],
55
+ { encoding: 'utf8' }
56
+ ).trim();
57
+
58
+ return prefix || null;
59
+ }
60
+
61
+
62
+ async function checkUrlExists(url) {
63
+ try {
64
+ const res = await fetch(url, { method: 'HEAD', redirect: 'follow' });
65
+ return res.ok;
66
+ } catch (err) {
67
+ throw new Error(`Network error while checking prebuilt availability: ${err.message} (${url})`);
68
+ }
69
+ }
70
+
71
+ async function downloadFile(url, tmpPath, destPath) {
72
+ const res = await fetch(url, { method: 'GET', redirect: 'follow' });
73
+ if (!res.ok) {
74
+ throw new Error(`Failed to download: ${res.statusText} (${url})`);
75
+ }
76
+
77
+ const fileStream = fs.createWriteStream(destPath);
78
+ const stream = require('stream');
79
+ const { promisify } = require('util');
80
+ const pipeline = promisify(stream.pipeline);
81
+
82
+ await pipeline(res.body, fileStream);
83
+ fs.renameSync(tmpPath, destPath);
84
+ }
85
+
86
+ function setExecutable(filePath) {
87
+ if (process.platform !== 'win32') {
88
+ fs.chmodSync(filePath, 0o755);
89
+ }
90
+ }
91
+
92
+ function writeFileExecutable(filePath, content) {
93
+ fs.writeFileSync(filePath, content, { encoding: 'utf8' });
94
+ setExecutable(filePath);
95
+ }
96
+
97
+ function getNpmGlobalBinDir() {
98
+ if (!isTruthy(process.env.npm_config_global)) return null;
99
+
100
+ const prefix = getPrefixFromEnvOrNpm();
101
+ if (!prefix) return null;
102
+
103
+ if (process.platform === 'win32') {
104
+ // On Windows, shims are in the prefix dir itself
105
+ return prefix;
106
+ }
107
+
108
+ // On Unix, shims are in <prefix>/bin
109
+ return path.join(prefix, 'bin');
110
+ }
111
+
112
+
113
+ function overwriteGlobalShim(nativeAbsPath) {
114
+ if (!isTruthy(process.env.npm_config_global))
115
+ return false;
116
+
117
+ if (!(process.env.npm_config_user_agent || '').includes('npm/')) {
118
+ log('Non-npm global install detected; skipping global shim overwrite.');
119
+ log('This may result in overhead introduced by the Node.js launch script.');
120
+ return false;
121
+ }
122
+
123
+ const globalBin = getNpmGlobalBinDir();
124
+ if (!globalBin) return false;
125
+
126
+ if (process.platform === 'win32') {
127
+ const cmdPath = path.join(globalBin, 'gdx.cmd');
128
+ const ps1Path = path.join(globalBin, 'gdx.ps1');
129
+
130
+ const cmd = [
131
+ '@echo off',
132
+ `"${nativeAbsPath}" %*`,
133
+ 'exit /b %ERRORLEVEL%',
134
+ ''
135
+ ].join('\r\n');
136
+
137
+ const ps1 = [
138
+ `& "${nativeAbsPath}" @args`,
139
+ 'exit $LASTEXITCODE',
140
+ ''
141
+ ].join('\r\n');
142
+
143
+ writeFileExecutable(cmdPath, cmd);
144
+ writeFileExecutable(ps1Path, ps1);
145
+ } else {
146
+ const shPath = path.join(globalBin, 'gdx');
147
+
148
+ const sh = [
149
+ '#!/usr/bin/env sh',
150
+ `exec "${nativeAbsPath}" "$@"`,
151
+ ''
152
+ ].join('\n');
153
+
154
+ writeFileExecutable(shPath, sh);
155
+ }
156
+ return true;
157
+ }
158
+
159
+ async function tryDownloadPrebuilt() {
160
+ const version = getPackageVersion();
161
+ const platform = process.platform;
162
+ const arch = process.arch;
163
+
164
+ // Currently only supporting win32-x64
165
+ if (platform !== 'win32' || arch !== 'x64') {
166
+ throw new Error(`gdx: prebuilt binary not available for ${platform}/${arch} yet. Please reinstall without GDX_USE_PREBUILT=1 (unset GDX_USE_PREBUILT or use GDX_BUILD_NATIVE=1).`);
167
+ }
168
+
169
+ const ext = platform === 'win32' ? '.exe' : '';
170
+ const assetName = `gdx-${platform}-${arch}${ext}`;
171
+ const url = `${PREBUILT_BASE_URL}/v${version}/${assetName}`;
172
+
173
+ log(`Checking availability of prebuilt binary: ${url}`);
174
+ const exists = await checkUrlExists(url);
175
+ if (!exists) {
176
+ throw new Error(`gdx: prebuilt binary not available for ${platform}/${arch} yet (404). Please reinstall without GDX_USE_PREBUILT=1 (unset GDX_USE_PREBUILT or use GDX_BUILD_NATIVE=1).`);
177
+ }
178
+
179
+ log(`Downloading prebuilt binary...`);
180
+ const tmpPath = path.join(NATIVE_DIR, `${assetName}.tmp`);
181
+ const finalPath = path.join(NATIVE_DIR, 'gdx' + ext);
182
+
183
+ ensureBinDir();
184
+ await downloadFile(url, tmpPath, finalPath);
185
+ setExecutable(finalPath);
186
+
187
+ log(`Prebuilt binary installed to ${finalPath}`);
188
+
189
+ writeInstallInfo({
190
+ mode: 'prebuilt',
191
+ platform,
192
+ arch,
193
+ version,
194
+ userAgent: process.env.npm_config_user_agent || null,
195
+ useNativeShim: overwriteGlobalShim(finalPath),
196
+ ts: (new Date).toLocaleString(),
197
+ binaryPath: finalPath
198
+ });
199
+ }
200
+
201
+ function tryBuildNative() {
202
+ log('Attempting local native build with Bun...');
203
+
204
+ // Check for bun
205
+ const bunCheck = spawnSync('bun', ['--version'], { encoding: 'utf8', shell: true });
206
+ if (bunCheck.error || bunCheck.status !== 0) {
207
+ throw new Error('Bun is not installed or not found in PATH. Cannot build native binary. Please install Bun or reinstall without GDX_BUILD_NATIVE=1. (unset GDX_BUILD_NATIVE or set GDX_USE_PREBUILT to use prebuilt binary if available)');
208
+ }
209
+
210
+ const platform = process.platform;
211
+ const arch = process.arch;
212
+ const isWin = platform === 'win32';
213
+ const binaryName = isWin ? 'gdx.exe' : 'gdx';
214
+ const finalPath = path.join(NATIVE_DIR, binaryName);
215
+
216
+ // Build command
217
+ const args = [
218
+ 'build',
219
+ PKG_SRC_PATH,
220
+ `--outfile=${finalPath}`,
221
+ '--compile',
222
+ '--bytecode',
223
+ '--production',
224
+ '--keep-names',
225
+ ];
226
+
227
+ ensureBinDir();
228
+ log(`Running: bun ${args.join(' ')}`);
229
+ const build = spawnSync('bun', args, { stdio: 'inherit', shell: true });
230
+
231
+ if (build.status !== 0) {
232
+ throw new Error('Native build failed. Please check output above.');
233
+ }
234
+
235
+ log(`Native binary built at ${finalPath}`);
236
+
237
+ writeInstallInfo({
238
+ mode: 'built',
239
+ platform,
240
+ arch,
241
+ version: getPackageVersion(),
242
+ userAgent: process.env.npm_config_user_agent || null,
243
+ useNativeShim: overwriteGlobalShim(finalPath),
244
+ ts: (new Date).toLocaleString(),
245
+ binaryPath: finalPath
246
+ });
247
+ }
248
+
249
+ async function main() {
250
+ const ignoreScripts = isTruthy(process.env.npm_config_ignore_scripts) ||
251
+ isTruthy(process.env.NPM_CONFIG_IGNORE_SCRIPTS);
252
+ if (ignoreScripts) {
253
+ log('Scripts ignored by configuration. Skipping native setup.');
254
+ return;
255
+ }
256
+
257
+ try {
258
+ if (isTruthy(process.env.GDX_USE_PREBUILT)) {
259
+ await tryDownloadPrebuilt();
260
+ } else if (isTruthy(process.env.GDX_BUILD_NATIVE)) {
261
+ tryBuildNative();
262
+ } else {
263
+ log('No native install requested (default). Using Node.js fallback.');
264
+ // Do nothing
265
+ }
266
+ } catch (err) {
267
+ error(err.message);
268
+ process.exit(1);
269
+ }
270
+ }
271
+
272
+ main();
Binary file