git0 0.2.5 → 0.2.7

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.
Files changed (75) hide show
  1. package/bun.lock +159 -0
  2. package/docs/404.html +2 -3
  3. package/docs/Footer/index.html +2 -3
  4. package/docs/assets/js/1df93b7f.d8c05d2c.js +2 -0
  5. package/docs/assets/js/22dd74f7.237398b4.js +1 -0
  6. package/docs/assets/js/28ab763d.5714aa16.js +1 -0
  7. package/docs/assets/js/299d276b.1a1baa1c.js +1 -0
  8. package/docs/assets/js/68cef36b.c312447e.js +1 -0
  9. package/docs/assets/js/c3a618e1.965a31da.js +1 -0
  10. package/docs/assets/js/{main.c71c09a5.js → main.cf858a7d.js} +2 -2
  11. package/docs/assets/js/runtime~main.7520dc36.js +1 -0
  12. package/docs/functions/git0/index.html +48 -0
  13. package/docs/functions/github-api/index.html +149 -0
  14. package/docs/functions/index.html +4 -5
  15. package/docs/functions/modules/index.html +30 -0
  16. package/docs/index.html +3 -4
  17. package/docs/lunr-index-1749613752315.json +1 -0
  18. package/docs/lunr-index.json +1 -1
  19. package/docs/search-doc-1749613752315.json +1 -0
  20. package/docs/search-doc.json +1 -1
  21. package/docs/sitemap.xml +1 -1
  22. package/docs-config/.docusaurus/DONT-EDIT-THIS-FOLDER +5 -0
  23. package/docs-config/.docusaurus/client-manifest.json +259 -0
  24. package/docs-config/.docusaurus/client-modules.js +8 -0
  25. package/docs-config/.docusaurus/codeTranslations.json +1 -0
  26. package/docs-config/.docusaurus/docusaurus-lunr-search/default/__plugin.json +4 -0
  27. package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/__mdx-loader-dependency.json +1 -0
  28. package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/__plugin.json +4 -0
  29. package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/p/docs-175.json +1 -0
  30. package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/p/index-466.json +1 -0
  31. package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/site-src-functions-git-0-1-md-d3e.json +19 -0
  32. package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/site-src-functions-git-0-md-299.json +19 -0
  33. package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/site-src-functions-github-api-md-28a.json +23 -0
  34. package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/site-src-functions-globals-md-4a8.json +19 -0
  35. package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/site-src-functions-index-md-c3a.json +23 -0
  36. package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/site-src-functions-modules-md-68c.json +19 -0
  37. package/docs-config/.docusaurus/docusaurus-plugin-content-docs/default/site-src-index-md-d14.json +21 -0
  38. package/docs-config/.docusaurus/docusaurus-plugin-content-pages/default/__plugin.json +4 -0
  39. package/docs-config/.docusaurus/docusaurus-plugin-google-gtag/default/__plugin.json +4 -0
  40. package/docs-config/.docusaurus/docusaurus.config.mjs +378 -0
  41. package/docs-config/.docusaurus/globalData.json +65 -0
  42. package/docs-config/.docusaurus/i18n.json +17 -0
  43. package/docs-config/.docusaurus/lunr.client.js +5 -0
  44. package/docs-config/.docusaurus/registry.js +15 -0
  45. package/docs-config/.docusaurus/routes.js +61 -0
  46. package/docs-config/.docusaurus/routesChunkNames.json +45 -0
  47. package/docs-config/.docusaurus/site-metadata.json +51 -0
  48. package/docs-config/.docusaurus/site-storage.json +4 -0
  49. package/docs-config/bun.lock +6139 -0
  50. package/docs-config/config/customize-docs.js +4 -2
  51. package/docs-config/docusaurus.config.ts +0 -9
  52. package/docs-config/src/functions/git0.md +101 -0
  53. package/docs-config/src/functions/github-api.md +744 -0
  54. package/docs-config/src/functions/modules.md +4 -0
  55. package/docs-config/src/functions/typedoc-sidebar.cjs +12 -1
  56. package/docs-config/src/pages/index.tsx +289 -279
  57. package/docs-config/tsconfig.json +1 -1
  58. package/package.json +10 -7
  59. package/src/git0.js +380 -0
  60. package/src/github-api.js +473 -0
  61. package/docs/assets/js/1df93b7f.dfdf0ef3.js +0 -2
  62. package/docs/assets/js/22dd74f7.5e857962.js +0 -1
  63. package/docs/assets/js/4a829dc8.728a4445.js +0 -1
  64. package/docs/assets/js/c3a618e1.50a89e4d.js +0 -1
  65. package/docs/assets/js/d140250a.62af53aa.js +0 -1
  66. package/docs/assets/js/runtime~main.ef55418f.js +0 -1
  67. package/docs/functions/globals/index.html +0 -57
  68. package/docs/lunr-index-1749601667754.json +0 -1
  69. package/docs/search-doc-1749601667754.json +0 -1
  70. package/docs-config/src/functions/globals.md +0 -153
  71. package/docs-config/src/index.md +0 -127
  72. package/docs-config/tailwind.config.js +0 -13
  73. package/git0.js +0 -646
  74. /package/docs/assets/js/{1df93b7f.dfdf0ef3.js.LICENSE.txt → 1df93b7f.d8c05d2c.js.LICENSE.txt} +0 -0
  75. /package/docs/assets/js/{main.c71c09a5.js.LICENSE.txt → main.cf858a7d.js.LICENSE.txt} +0 -0
package/git0.js DELETED
@@ -1,646 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import inquirer from 'inquirer';
4
- import chalk from 'chalk';
5
- import { execSync, spawn } from 'child_process';
6
- import grab from 'grab-api.js';
7
- import * as tar from 'tar'
8
- import { pipeline } from 'stream/promises';
9
- import fs from 'fs';
10
- import path from 'path';
11
- import gitUrlParse from 'git-url-parse';
12
- import os from 'os';
13
-
14
- const GITHUB_API = 'https://api.github.com/search/repositories';
15
- const RESULTS_PER_PAGE = 10;
16
- const TOKEN = process.env.GITHUB_TOKEN;
17
-
18
- const githubHelpUrl = 'https://github.com/settings/personal-access-tokens/new'
19
- grab('', {
20
- setDefaults: true,
21
- debug: false,
22
- onError: (error) => {
23
- if (error.includes('403')) {
24
- log(chalk.red('Rate limit exceeded. Please set env var GITHUB_TOKEN. Help:\n' + githubHelpUrl));
25
- process.exit(1);
26
-
27
- }
28
- }
29
- }
30
- )
31
-
32
- function printLogo() {
33
- console.log(chalk.cyan(` ___
34
- __ _(_)‾|_ / _ \\
35
- / _ | | __| | | |
36
- | (_| | | |_| |_| |
37
- \\__, |_|\\__|\\___/
38
- |___/`))
39
- }
40
-
41
- // Detect current operating system and architecture
42
- function getCurrentPlatform() {
43
- const platform = os.platform();
44
- const arch = os.arch();
45
-
46
- const platformMap = {
47
- 'win32': 'windows',
48
- 'darwin': 'macos',
49
- 'linux': 'linux'
50
- };
51
-
52
- const archMap = {
53
- 'x64': 'x86_64',
54
- 'arm64': 'arm64',
55
- 'arm': 'arm',
56
- 'ia32': 'i386'
57
- };
58
-
59
- return {
60
- os: platformMap[platform] || platform,
61
- arch: archMap[arch] || arch,
62
- platform,
63
- architecture: arch
64
- };
65
- }
66
-
67
- // Get releases for a repository
68
- async function getRepositoryReleases(owner, repo) {
69
- try {
70
- const response = await grab(`https://api.github.com/repos/${owner}/${repo}/releases`, {
71
- headers: TOKEN ? { Authorization: `token ${TOKEN}` } : {},
72
- per_page: 5 // Get latest 5 releases
73
-
74
- });
75
-
76
- return response;
77
- } catch (error) {
78
- return [];
79
- }
80
- }
81
-
82
- // Categorize releases by platform
83
- function categorizeReleasesByPlatform(releases) {
84
- const platformKeywords = {
85
- windows: ['win', 'windows', 'win32', 'win64', '.exe', '.msi'],
86
- macos: ['mac', 'macos', 'darwin', 'osx', '.dmg', '.pkg'],
87
- linux: ['linux', 'ubuntu', 'debian', '.deb', '.rpm', '.tar.gz', '.AppImage']
88
- };
89
-
90
- const archKeywords = {
91
- x86_64: ['x86_64', 'x64', 'amd64', '64'],
92
- arm64: ['arm64', 'aarch64'],
93
- arm: ['arm', 'armv7'],
94
- i386: ['i386', 'x86', '32']
95
- };
96
-
97
- const categorizedReleases = [];
98
-
99
- Object.entries(releases).forEach(([key, release]) => {
100
- const platformAssets = {
101
- windows: [],
102
- macos: [],
103
- linux: [],
104
- universal: []
105
- };
106
-
107
- release.assets.forEach(asset => {
108
- const name = asset.name.toLowerCase();
109
- let categorized = false;
110
-
111
- // Check each platform
112
- Object.entries(platformKeywords).forEach(([platform, keywords]) => {
113
- if (keywords.some(keyword => name.includes(keyword.toLowerCase()))) {
114
- // Determine architecture
115
- let detectedArch = 'unknown';
116
- Object.entries(archKeywords).forEach(([arch, archKeys]) => {
117
- if (archKeys.some(archKey => name.includes(archKey.toLowerCase()))) {
118
- detectedArch = arch;
119
- }
120
- });
121
-
122
- platformAssets[platform].push({
123
- ...asset,
124
- detectedArch,
125
- platform
126
- });
127
- categorized = true;
128
- }
129
- });
130
-
131
- // If not categorized, check for universal binaries
132
- if (!categorized && (name.includes('universal') || name.includes('all') ||
133
- (!name.includes('win') && !name.includes('mac') && !name.includes('linux')))) {
134
- platformAssets.universal.push({
135
- ...asset,
136
- detectedArch: 'universal',
137
- platform: 'universal'
138
- });
139
- }
140
- });
141
-
142
- // Only include releases that have assets
143
- const hasAssets = Object.values(platformAssets).some(assets => assets.length > 0);
144
- if (hasAssets) {
145
- categorizedReleases.push({
146
- ...release,
147
- platformAssets
148
- });
149
- }
150
- });
151
-
152
- return categorizedReleases;
153
- }
154
-
155
- // Filter releases for current platform (for compatibility indicator)
156
- function filterReleasesByPlatform(releases, currentPlatform) {
157
- const categorized = categorizeReleasesByPlatform(releases);
158
- return categorized.filter(release =>
159
- release.platformAssets[currentPlatform.os].length > 0 ||
160
- release.platformAssets.universal.length > 0
161
- );
162
- }
163
-
164
-
165
- // Download and install package
166
- async function downloadPackage(asset, targetDir) {
167
- const fileName = asset.name;
168
- const downloadPath = path.join(targetDir, fileName);
169
-
170
- log(chalk.blue(`📦 Downloading ${fileName}...`));
171
- printLogo()
172
- try {
173
- const response = await grab(asset.browser_download_url, {
174
- headers: TOKEN ? { Authorization: `token ${TOKEN}` } : {},
175
- onStream: async (res) => {
176
- const nodeStream = (await import('stream'))?.Readable.fromWeb(res);
177
- await new Promise((resolve, reject) => {
178
- nodeStream.pipe(fs.createWriteStream(downloadPath)).on('finish', resolve).on('error', reject);
179
- });
180
- }
181
- });
182
-
183
- log(chalk.green(`✅ Downloaded ${fileName} to ${downloadPath}`));
184
-
185
- // Try to make executable if it's a binary
186
- if (process.platform !== 'win32' && !fileName.includes('.')) {
187
- try {
188
- fs.chmodSync(downloadPath, '755');
189
- log(chalk.green(`✅ Made ${fileName} executable`));
190
- } catch (error) {
191
- log(chalk.yellow(`⚠️ Could not make ${fileName} executable`));
192
- }
193
- }
194
-
195
- // Provide installation instructions
196
- provideInstallationInstructions(downloadPath, asset);
197
-
198
- } catch (error) {
199
- console.error(chalk.red(`❌ Failed to download ${fileName}:`), error.message);
200
- }
201
- }
202
-
203
- // Provide platform-specific installation instructions
204
- function provideInstallationInstructions(filePath, asset) {
205
- const fileName = asset.name;
206
- const platform = getCurrentPlatform();
207
-
208
- if (platform.platform === 'win32') {
209
- if (fileName.endsWith('.exe')) {
210
- log(chalk.white(' Run the executable:'));
211
- log(chalk.gray(` ${filePath}`));
212
- } else if (fileName.endsWith('.msi')) {
213
- log(chalk.white(' Install the MSI package:'));
214
- log(chalk.gray(` msiexec /i "${filePath}"`));
215
- }
216
- } else if (platform.platform === 'darwin') {
217
- if (fileName.endsWith('.dmg')) {
218
- log(chalk.white(' Mount and install the DMG:'));
219
- log(chalk.gray(` open "${filePath}"`));
220
- } else if (fileName.endsWith('.pkg')) {
221
- log(chalk.white(' Install the package:'));
222
- log(chalk.gray(` sudo installer -pkg "${filePath}" -target /`));
223
- }
224
- } else {
225
- if (fileName.endsWith('.deb')) {
226
- log(chalk.white(' Install the DEB package:'));
227
- log(chalk.gray(` sudo dpkg -i "${filePath}"`));
228
- } else if (fileName.endsWith('.rpm')) {
229
- log(chalk.white(' Install the RPM package:'));
230
- log(chalk.gray(` sudo rpm -i "${filePath}"`));
231
- } else if (fileName.endsWith('.AppImage')) {
232
- log(chalk.white(' Run the AppImage:'));
233
- log(chalk.gray(` chmod +x "${filePath}" && "${filePath}"`));
234
- } else if (!fileName.includes('.')) {
235
- log(chalk.white(' Binary is ready to use:'));
236
- log(chalk.gray(` "${filePath}"`));
237
- log(chalk.white(' Consider moving to PATH:'));
238
- log(chalk.gray(` sudo mv "${filePath}" /usr/local/bin/`));
239
- }
240
- }
241
- }
242
-
243
- // Show package selection menu organized by platform
244
- async function showPackageMenu(selectedRepo) {
245
- const currentPlatform = getCurrentPlatform();
246
- const releaseChoices = [];
247
- const limitReleases = 2;
248
-
249
- // Add section headers and organize by platform
250
- selectedRepo.allReleases.slice(0, limitReleases).forEach(release => {
251
- const platforms = ['windows', 'macos', 'linux', 'universal'];
252
-
253
- platforms.forEach(platform => {
254
- const assets = release.platformAssets[platform];
255
- if (assets.length > 0) {
256
- // Add platform header
257
- const platformEmoji = {
258
- windows: '🪟',
259
- macos: '🍎',
260
- linux: '🐧',
261
- universal: '🌐'
262
- };
263
-
264
- const platformName = {
265
- windows: 'Windows',
266
- macos: 'macOS',
267
- linux: 'Linux',
268
- universal: 'Universal'
269
- };
270
-
271
- const isCurrentPlatform = platform === currentPlatform.os || platform === 'universal';
272
- const platformHeader = isCurrentPlatform
273
- ? chalk.green(`${platformEmoji[platform]} ${platformName[platform]} (Your Platform)`)
274
- : chalk.gray(`${platformEmoji[platform]} ${platformName[platform]}`);
275
-
276
- // Add separator if not first platform in this release
277
- const needsSeparator = releaseChoices.length > 0 &&
278
- !releaseChoices[releaseChoices.length - 1].name.includes('────');
279
-
280
- if (needsSeparator) {
281
- releaseChoices.push({
282
- name: chalk.gray('────────────────────────────────'),
283
- disabled: true
284
- });
285
- }
286
-
287
- releaseChoices.push({
288
- name: `${chalk.bold(release.tag_name)} - ${platformHeader}`,
289
- disabled: true
290
- });
291
-
292
- // Add assets for this platform
293
- assets.forEach(asset => {
294
- const sizeStr = (asset.size / 1024 / 1024).toFixed(2);
295
- const archInfo = asset.detectedArch !== 'unknown' && asset.detectedArch !== 'universal'
296
- ? chalk.cyan(`[${asset.detectedArch}]`)
297
- : '';
298
-
299
- const highlight = isCurrentPlatform ? chalk.white : chalk.gray;
300
-
301
- releaseChoices.push({
302
- name: ` ${highlight(`${asset.name} ${archInfo} (${sizeStr} MB)`)}`,
303
- value: { release, asset }
304
- });
305
- });
306
- }
307
- });
308
- });
309
-
310
- if (releaseChoices.filter(choice => !choice.disabled).length === 0) {
311
- log(chalk.yellow('No packages found for download.'));
312
- return;
313
- }
314
-
315
- const { selectedPackage } = await inquirer.prompt({
316
- type: 'list',
317
- name: 'selectedPackage',
318
- message: 'Select a package to download:',
319
- choices: releaseChoices,
320
- pageSize: 15
321
- });
322
-
323
- const downloadDir = path.resolve(process.cwd());
324
- fs.mkdirSync(downloadDir, { recursive: true });
325
- await downloadPackage(selectedPackage.asset, downloadDir);
326
- }
327
-
328
- function getIdeCommand() {
329
- const ides = [
330
- { name: 'Cursor', cmd: 'cursor' },
331
- { name: 'Windsurf', cmd: 'windsurf' },
332
- { name: 'VSCode', cmd: 'code' },
333
- { name: 'Code Server', cmd: 'code-server' },
334
- { name: 'Neovim', cmd: 'nvim' },
335
- { name: 'Webstorm', cmd: 'webstorm' }
336
- ];
337
-
338
- for (const ide of ides) {
339
- try {
340
- execSync(
341
- process.platform === 'win32'
342
- ? `where ${ide.cmd}`
343
- : `command -v ${ide.cmd}`,
344
- { stdio: 'ignore' }
345
- );
346
- return ide;
347
- } catch (error) {
348
- continue;
349
- }
350
- }
351
- return null;
352
- }
353
-
354
- export function openInIDE(targetDir) {
355
- const ide = getIdeCommand();
356
- if (!ide) {
357
- log(chalk.yellow('⚠️ No supported IDE found'));
358
- return;
359
- }
360
-
361
- try {
362
- const args = ide.cmd === 'code-server'
363
- ? [targetDir, '--open']
364
- : [targetDir];
365
-
366
- spawn(ide.cmd, args, {
367
- detached: true,
368
- stdio: 'ignore',
369
- shell: process.platform === 'win32'
370
- }).unref();
371
-
372
- // open readme after 3 seconds
373
- setTimeout(() => {
374
-
375
- const readme = fs.existsSync('./readme.md') ? './readme.md' :
376
- fs.existsSync('./Readme.md') ? './Readme.md' :
377
- fs.existsSync('./README.md') ? './README.md' :
378
- fs.existsSync('./package.json') ? './package.json' :
379
- null;
380
-
381
- if (readme)
382
- spawn(ide.cmd, ide.cmd === 'code-server'
383
- ? [readme, '--open']
384
- : [readme], {
385
- detached: true,
386
- stdio: 'ignore',
387
- shell: process.platform === 'win32'
388
- }).unref();
389
- }, 3000);
390
-
391
- log(chalk.green(`🚀 Opening ${path.basename(targetDir)} in ${ide.name}`));
392
- } catch (error) {
393
- console.error(chalk.red(`❌ Failed to open ${ide.name}:`), error.message);
394
- }
395
- }
396
-
397
- export async function installDependencies(targetDir) {
398
- process.chdir(targetDir);
399
-
400
-
401
- // Project type detection
402
- const detectors = {
403
- nodejs: () => fs.existsSync('package.json'),
404
- docker: () => fs.existsSync('Dockerfile'),
405
- python: () => fs.existsSync('requirements.txt') || fs.existsSync('setup.py'),
406
- rust: () => fs.existsSync('Cargo.toml'),
407
- go: () => fs.existsSync('go.mod')
408
- };
409
-
410
- // Install commands for each project type
411
- const installers = {
412
- nodejs: () => {
413
- try {
414
- execSync(
415
- process.platform === 'win32'
416
- ? `where bun`
417
- : `command -v bun`,
418
- { stdio: 'ignore' }
419
- );
420
- runCommand('bun install');
421
- runCommand('bun run dev; bun run start');
422
- } catch (error) {
423
- runCommand('npm install');
424
- runCommand('npm run dev; npm run start');
425
- }
426
- },
427
- docker: () => {
428
- if (fs.existsSync('docker-compose.yml')) {
429
- runCommand('sudo docker-compose up -d');
430
- } else if (fs.existsSync('Dockerfile')) {
431
- runCommand('sudo docker build -t project .');
432
- }
433
- },
434
- python: () => {
435
- runCommand('python -m venv .venv');
436
- runCommand('source .venv/bin/activate');
437
-
438
- if (fs.existsSync('requirements.txt')) {
439
- runCommand('pip install -r requirements.txt');
440
- }
441
- if (fs.existsSync('setup.py')) {
442
- runCommand('pip install -e .');
443
- }
444
- },
445
- rust: () => runCommand('cargo build'),
446
- go: () => runCommand('go mod tidy')
447
- };
448
-
449
- // Run detections and installations
450
- Object.entries(detectors).forEach(([name, check]) => {
451
- if (check()) {
452
- // log(chalk.yellow(`⚙️ Detected ${name} project`));
453
- installers[name]?.();
454
- }
455
- });
456
- }
457
-
458
- function runCommand(cmd) {
459
- log(chalk.cyan(`🚀 Running: ${cmd}`));
460
- try {
461
- execSync(cmd, { stdio: 'inherit' });
462
- } catch (error) {
463
- console.error(chalk.red(`❌ Failed: ${cmd}`));
464
- }
465
- }
466
-
467
- export async function searchRepositories(query) {
468
- try {
469
- const response = await grab(GITHUB_API, {
470
- q: `${query} in:name`,
471
- sort: 'stars',
472
- order: 'desc',
473
- per_page: RESULTS_PER_PAGE,
474
- debug: false,
475
- headers: TOKEN ? { Authorization: `token ${TOKEN}` } : {}
476
- });
477
-
478
- if (response.error || !response.items)
479
- return log("No response")
480
-
481
- // Check for releases for each repository
482
- const reposWithReleases = await Promise.all(
483
- response.items.map(async (repo) => {
484
- const releases = await getRepositoryReleases(repo.owner.login, repo.name);
485
- const currentPlatform = getCurrentPlatform();
486
- const compatibleReleases = filterReleasesByPlatform(releases, currentPlatform);
487
- const categorizedReleases = categorizeReleasesByPlatform(releases);
488
-
489
- return {
490
- ...repo,
491
- hasReleases: releases.length > 0,
492
- hasCompatibleReleases: compatibleReleases.length > 0,
493
- releases: compatibleReleases,
494
- allReleases: categorizedReleases
495
- };
496
- })
497
- );
498
-
499
- return reposWithReleases;
500
- } catch (error) {
501
- console.error(chalk.red('Search failed:'), error.message);
502
- process.exit(1);
503
- }
504
- }
505
-
506
- export async function downloadRepo(repo) {
507
- const parsed = gitUrlParse(repo);
508
- const defaultDir = path.resolve(process.cwd(), parsed.name);
509
- const extractPath = getAvailableDirectoryName(defaultDir);
510
-
511
- // if it picks up a larger owner name, slice to the last part
512
- if (parsed.owner.includes('/'))
513
- parsed.owner = parsed.owner.split('/').slice(-1).join('');
514
-
515
- fs.mkdirSync(extractPath, { recursive: true });
516
- log(chalk.blue(`📦 Downloading ${parsed.name} into ${path.basename(extractPath)}...`));
517
- printLogo()
518
-
519
- let url = `https://api.github.com/repos/${parsed.owner}/${parsed.name}/tarball/${parsed.default_branch || 'master'}`;
520
-
521
- try {
522
-
523
- var params = {
524
- headers: TOKEN ? { Authorization: `token ${TOKEN}` } : {},
525
- onStream: async (res) => {
526
-
527
- const nodeStream = (await import('stream'))?.Readable.fromWeb(res);
528
- await new Promise((resolve, reject) => {
529
- nodeStream.pipe(tar.x({
530
- C: extractPath,
531
- strip: 1
532
- })).on('finish', resolve).on('error', reject);
533
- });
534
- }
535
- }
536
-
537
- var response = await grab(url, params);
538
-
539
- if (response.error)
540
- response = await grab(url.replace("/master", "/main"), params);
541
-
542
-
543
- setTimeout(() => {
544
- openInIDE(extractPath);
545
- }, 1000);
546
- installDependencies(extractPath);
547
- } catch (error) {
548
- console.error(chalk.red('Download failed:'), error.message);
549
- process.exit(1);
550
- }
551
- }
552
-
553
- function getAvailableDirectoryName(basePath) {
554
- if (!fs.existsSync(basePath)) return basePath;
555
- let counter = 2;
556
- let newPath;
557
- while (true) {
558
- newPath = `${basePath}-${counter}`;
559
- if (!fs.existsSync(newPath)) return newPath;
560
- counter++;
561
- }
562
- }
563
-
564
- async function main() {
565
- printLogo()
566
- const args = process.argv.slice(2);
567
- if (!args.length) {
568
- log(chalk.yellow('Usage: gg <search-query>'));
569
- process.exit(1);
570
- }
571
-
572
- const query = args.join(' ');
573
- const currentPlatform = getCurrentPlatform();
574
-
575
-
576
- let repoUrl = null;
577
-
578
- // Try parsing as a GitHub URL or shorthand
579
- let parsed = null;
580
-
581
- if (query.includes('github.com') || query.startsWith('git@github.com:') || query.startsWith('https://') || query.startsWith('git://')) {
582
- parsed = gitUrlParse(query);
583
- } else if (/^[\w-]+\/[\w.-]+$/.test(query)) {
584
- // Shorthand owner/repo
585
- parsed = gitUrlParse(`https://github.com/${query}`);
586
- }
587
-
588
- if (parsed && parsed.owner && parsed.name) {
589
- await downloadRepo(parsed.href);
590
- return;
591
- }
592
-
593
- const results = await searchRepositories(query);
594
-
595
- if (!results || !results.length) {
596
- log(chalk.yellow('No repositories found'));
597
- return;
598
- }
599
-
600
-
601
- const { selectedRepo } = await inquirer.prompt({
602
- type: 'list',
603
- name: 'selectedRepo',
604
- message: 'Select a repository to download:',
605
- choices: results.map(repo => {
606
- const packageInfo = repo.hasCompatibleReleases
607
- ? chalk.green(' 📦 Packages available')
608
- : repo.hasReleases
609
- ? chalk.yellow(' 📦 Packages (other platforms)')
610
- : '';
611
-
612
- return {
613
- name: `${chalk.bold(repo.full_name)} - ${chalk.gray(repo.description || 'No description')}
614
- ${chalk.yellow(`★ ${repo.stargazers_count}`)} | ${chalk.blue(repo.language || 'Unknown')}${packageInfo}`,
615
- value: repo
616
- };
617
- })
618
- });
619
-
620
- // If the selected repo has any releases, show download options
621
- if (selectedRepo.hasReleases || selectedRepo.hasCompatibleReleases) {
622
- const { downloadChoice } = await inquirer.prompt({
623
- type: 'list',
624
- name: 'downloadChoice',
625
- message: 'This repository has downloadable packages. What would you like to do?',
626
- choices: [
627
- { name: '📦 Download package/binary', value: 'package' },
628
- { name: '📂 Download source code', value: 'source' },
629
- { name: '📦📂 Download both package and source', value: 'both' }
630
- ]
631
- });
632
-
633
- if (downloadChoice === 'package' || downloadChoice === 'both') {
634
- await showPackageMenu(selectedRepo);
635
- }
636
-
637
- if (downloadChoice === 'source' || downloadChoice === 'both') {
638
- await downloadRepo(selectedRepo.url);
639
- }
640
- } else {
641
- // No packages, just download source
642
- await downloadRepo(selectedRepo.url);
643
- }
644
- }
645
-
646
- main();