infinitty 0.1.0
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/bin/cli.js +68 -0
- package/package.json +46 -0
- package/scripts/postinstall.js +133 -0
package/bin/cli.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require('child_process')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const fs = require('fs')
|
|
6
|
+
|
|
7
|
+
const binDir = path.join(__dirname, '..', '.binary')
|
|
8
|
+
const platform = process.platform
|
|
9
|
+
const arch = process.arch
|
|
10
|
+
|
|
11
|
+
// Tauri produces different structures per platform
|
|
12
|
+
const binaryMap = {
|
|
13
|
+
darwin: {
|
|
14
|
+
x64: 'Infinitty.app/Contents/MacOS/Infinitty',
|
|
15
|
+
arm64: 'Infinitty.app/Contents/MacOS/Infinitty'
|
|
16
|
+
},
|
|
17
|
+
win32: {
|
|
18
|
+
x64: 'Infinitty.exe'
|
|
19
|
+
},
|
|
20
|
+
linux: {
|
|
21
|
+
x64: 'infinitty.AppImage'
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const relativePath = binaryMap[platform]?.[arch]
|
|
26
|
+
|
|
27
|
+
if (!relativePath) {
|
|
28
|
+
console.error(`Platform ${platform}-${arch} not supported`)
|
|
29
|
+
console.error('Supported platforms: macOS (x64, arm64), Windows (x64), Linux (x64)')
|
|
30
|
+
process.exit(1)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const binaryPath = path.join(binDir, relativePath)
|
|
34
|
+
|
|
35
|
+
if (!fs.existsSync(binaryPath)) {
|
|
36
|
+
console.error('Binary not found. Running postinstall...')
|
|
37
|
+
console.error(`Expected: ${binaryPath}`)
|
|
38
|
+
|
|
39
|
+
// Try to run postinstall
|
|
40
|
+
try {
|
|
41
|
+
require('../scripts/postinstall')
|
|
42
|
+
} catch (e) {
|
|
43
|
+
console.error('Failed to install binary:', e.message)
|
|
44
|
+
console.error('Try reinstalling: npm install -g infinitty')
|
|
45
|
+
process.exit(1)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Make executable on Unix (AppImage needs this)
|
|
50
|
+
if (platform !== 'win32') {
|
|
51
|
+
try {
|
|
52
|
+
fs.chmodSync(binaryPath, 0o755)
|
|
53
|
+
} catch (e) {
|
|
54
|
+
// Ignore if already executable
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const child = spawn(binaryPath, process.argv.slice(2), {
|
|
59
|
+
stdio: 'inherit',
|
|
60
|
+
env: process.env
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
child.on('error', (err) => {
|
|
64
|
+
console.error('Failed to start Infinitty:', err.message)
|
|
65
|
+
process.exit(1)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
child.on('close', (code) => process.exit(code || 0))
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "infinitty",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Infinitty - An AI-powered hybrid terminal with file explorer",
|
|
5
|
+
"bin": {
|
|
6
|
+
"infinitty": "./bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node scripts/postinstall.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin",
|
|
13
|
+
"scripts"
|
|
14
|
+
],
|
|
15
|
+
"os": [
|
|
16
|
+
"darwin",
|
|
17
|
+
"linux",
|
|
18
|
+
"win32"
|
|
19
|
+
],
|
|
20
|
+
"cpu": [
|
|
21
|
+
"x64",
|
|
22
|
+
"arm64"
|
|
23
|
+
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=16"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"terminal",
|
|
29
|
+
"cli",
|
|
30
|
+
"ai",
|
|
31
|
+
"tauri",
|
|
32
|
+
"desktop",
|
|
33
|
+
"hybrid-terminal",
|
|
34
|
+
"file-explorer"
|
|
35
|
+
],
|
|
36
|
+
"author": "Jason Kneen",
|
|
37
|
+
"license": "AGPL-3.0-or-later",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/jasonkneen/infinitty.git"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/jasonkneen/infinitty",
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/jasonkneen/infinitty/issues"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
const https = require('https')
|
|
2
|
+
const fs = require('fs')
|
|
3
|
+
const path = require('path')
|
|
4
|
+
const { execSync } = require('child_process')
|
|
5
|
+
|
|
6
|
+
const pkg = require('../package.json')
|
|
7
|
+
const version = pkg.version
|
|
8
|
+
const platform = process.platform
|
|
9
|
+
const arch = process.arch
|
|
10
|
+
|
|
11
|
+
// Map Node platform/arch to Tauri target names
|
|
12
|
+
// NOTE: Currently only macOS is supported. Linux/Windows coming soon.
|
|
13
|
+
const targetMap = {
|
|
14
|
+
darwin: {
|
|
15
|
+
x64: 'x86_64-apple-darwin',
|
|
16
|
+
arm64: 'aarch64-apple-darwin'
|
|
17
|
+
}
|
|
18
|
+
// TODO: Add when builds are fixed
|
|
19
|
+
// win32: { x64: 'x86_64-pc-windows-msvc' },
|
|
20
|
+
// linux: { x64: 'x86_64-unknown-linux-gnu' }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const target = targetMap[platform]?.[arch]
|
|
24
|
+
|
|
25
|
+
if (!target) {
|
|
26
|
+
console.log(`Platform ${platform}-${arch} not yet supported`)
|
|
27
|
+
console.log('Currently supported: macOS (x64, arm64)')
|
|
28
|
+
console.log('Linux and Windows coming soon!')
|
|
29
|
+
process.exit(0)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const binDir = path.join(__dirname, '..', '.binary')
|
|
33
|
+
const appName = 'Infinitty'
|
|
34
|
+
|
|
35
|
+
// GitHub releases URL pattern
|
|
36
|
+
const baseUrl = `https://github.com/jasonkneen/infinitty/releases/download/v${version}`
|
|
37
|
+
|
|
38
|
+
// Tauri artifact naming varies by platform
|
|
39
|
+
function getDownloadUrl() {
|
|
40
|
+
if (platform === 'darwin') {
|
|
41
|
+
// macOS - compressed .app bundle (Tauri uses short arch names)
|
|
42
|
+
if (arch === 'arm64') {
|
|
43
|
+
return `${baseUrl}/${appName}_aarch64.app.tar.gz`
|
|
44
|
+
}
|
|
45
|
+
return `${baseUrl}/${appName}_x64.app.tar.gz`
|
|
46
|
+
}
|
|
47
|
+
// TODO: Add Linux/Windows when builds are fixed
|
|
48
|
+
return null
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const downloadUrl = getDownloadUrl()
|
|
52
|
+
|
|
53
|
+
if (!downloadUrl) {
|
|
54
|
+
console.error('Could not determine download URL')
|
|
55
|
+
process.exit(1)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.log(`Downloading Infinitty for ${platform}-${arch}...`)
|
|
59
|
+
console.log(`Version: ${version}`)
|
|
60
|
+
console.log(`URL: ${downloadUrl}`)
|
|
61
|
+
|
|
62
|
+
if (!fs.existsSync(binDir)) {
|
|
63
|
+
fs.mkdirSync(binDir, { recursive: true })
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function download(url, dest) {
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
const file = fs.createWriteStream(dest)
|
|
69
|
+
|
|
70
|
+
const request = (url) => {
|
|
71
|
+
https.get(url, (response) => {
|
|
72
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
73
|
+
// Follow redirect
|
|
74
|
+
request(response.headers.location)
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
if (response.statusCode === 404) {
|
|
78
|
+
reject(new Error(`Release not found: v${version}\nMake sure GitHub release v${version} exists with the binary assets.`))
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
if (response.statusCode !== 200) {
|
|
82
|
+
reject(new Error(`HTTP ${response.statusCode}: ${url}`))
|
|
83
|
+
return
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const totalBytes = parseInt(response.headers['content-length'], 10)
|
|
87
|
+
let downloadedBytes = 0
|
|
88
|
+
|
|
89
|
+
response.on('data', (chunk) => {
|
|
90
|
+
downloadedBytes += chunk.length
|
|
91
|
+
if (totalBytes) {
|
|
92
|
+
const percent = Math.round((downloadedBytes / totalBytes) * 100)
|
|
93
|
+
process.stdout.write(`\rDownloading... ${percent}%`)
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
response.pipe(file)
|
|
98
|
+
file.on('finish', () => {
|
|
99
|
+
file.close()
|
|
100
|
+
console.log('\nDownload complete!')
|
|
101
|
+
resolve()
|
|
102
|
+
})
|
|
103
|
+
}).on('error', reject)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
request(url)
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function install() {
|
|
111
|
+
try {
|
|
112
|
+
// macOS: Download and extract .tar.gz
|
|
113
|
+
const archiveFile = path.join(binDir, 'download.tar.gz')
|
|
114
|
+
await download(downloadUrl, archiveFile)
|
|
115
|
+
|
|
116
|
+
console.log('Extracting app bundle...')
|
|
117
|
+
execSync(`tar -xzf "${archiveFile}" -C "${binDir}"`, { stdio: 'inherit' })
|
|
118
|
+
fs.unlinkSync(archiveFile)
|
|
119
|
+
|
|
120
|
+
console.log(`\nInfinitty v${version} installed!`)
|
|
121
|
+
console.log('Run with: infinitty')
|
|
122
|
+
|
|
123
|
+
} catch (error) {
|
|
124
|
+
console.error('\nFailed to install binary:', error.message)
|
|
125
|
+
console.error('\nTroubleshooting:')
|
|
126
|
+
console.error(`1. Check if release v${version} exists: https://github.com/jasonkneen/infinitty/releases`)
|
|
127
|
+
console.error('2. Ensure the release has binary assets for your platform')
|
|
128
|
+
console.error('3. Try installing again: npm install -g infinitty')
|
|
129
|
+
process.exit(1)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
install()
|