@jetbrains/junie-cli 1.0.0 → 99.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/index.js +16 -0
- package/getExecutable.js +34 -0
- package/package.json +25 -7
- package/postinstall.js +117 -0
package/bin/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const {spawnSync} = require('child_process')
|
|
3
|
+
const {getExecutable} = require('../getExecutable')
|
|
4
|
+
|
|
5
|
+
function main() {
|
|
6
|
+
try {
|
|
7
|
+
const exe = getExecutable()
|
|
8
|
+
const result = spawnSync(exe, process.argv.slice(2), {stdio: 'inherit'})
|
|
9
|
+
process.exit(result.status ?? 0)
|
|
10
|
+
} catch (error) {
|
|
11
|
+
console.error('[Junie] Error:', error.message)
|
|
12
|
+
process.exit(1)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
main()
|
package/getExecutable.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const { platform } = require("node:os")
|
|
4
|
+
|
|
5
|
+
function getExpectedBinaryPath() {
|
|
6
|
+
const workDir = path.resolve(__dirname, 'bin', 'junie')
|
|
7
|
+
|
|
8
|
+
return platform() === 'darwin'
|
|
9
|
+
? path.join(workDir, 'Applications', 'junie.app', 'Contents', 'MacOS', 'junie')
|
|
10
|
+
: path.join(workDir, 'junie', 'bin', 'junie')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
function getExecutable() {
|
|
15
|
+
const markerFile = path.resolve(__dirname, 'bin', 'junie.download')
|
|
16
|
+
|
|
17
|
+
if (fs.existsSync(markerFile)) {
|
|
18
|
+
const binaryPath = getExpectedBinaryPath()
|
|
19
|
+
|
|
20
|
+
if (fs.existsSync(binaryPath)) {
|
|
21
|
+
return binaryPath
|
|
22
|
+
} else {
|
|
23
|
+
console.error('Junie binary not found. Please re-install the package')
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
console.error('Junie download is corrupted. Please re-install the package')
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
module.exports = {
|
|
32
|
+
getExpectedBinaryPath,
|
|
33
|
+
getExecutable,
|
|
34
|
+
};
|
package/package.json
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jetbrains/junie-cli",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
3
|
+
"version": "99.1.0",
|
|
4
|
+
"junieVersion": "99.1",
|
|
5
|
+
"description": "Junie command‑line client",
|
|
6
|
+
"license": "SEE LICENSE IN LICENSE.md",
|
|
7
|
+
"repository": "https://github.com/jetbrains-junie/junie",
|
|
8
|
+
"homepage": "https://github.com/jetbrains-junie/junie#readme",
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/jetbrains-junie/junie/issues"
|
|
11
|
+
},
|
|
12
|
+
"main": "bin/index.js",
|
|
13
|
+
"bin": {
|
|
14
|
+
"junie": "bin/index.js"
|
|
15
|
+
},
|
|
9
16
|
"scripts": {
|
|
10
|
-
"
|
|
17
|
+
"postinstall": "node postinstall.js"
|
|
18
|
+
},
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=20"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"bin/",
|
|
24
|
+
"postinstall.js",
|
|
25
|
+
"getExecutable.js"
|
|
26
|
+
],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"unzipper": "0.12.3"
|
|
11
29
|
}
|
|
12
30
|
}
|
package/postinstall.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require("path")
|
|
4
|
+
const fs = require("fs")
|
|
5
|
+
const { pipeline } = require("stream/promises")
|
|
6
|
+
const unzipper = require('unzipper')
|
|
7
|
+
const os = require("os")
|
|
8
|
+
const { getExpectedBinaryPath } = require("./getExecutable")
|
|
9
|
+
|
|
10
|
+
const ARCH_MAP = {
|
|
11
|
+
x64: 'amd64',
|
|
12
|
+
amd64: 'amd64',
|
|
13
|
+
arm64: 'aarch64',
|
|
14
|
+
aarch64: 'aarch64'
|
|
15
|
+
}
|
|
16
|
+
const OS_MAP = {
|
|
17
|
+
linux: 'linux',
|
|
18
|
+
darwin: 'macos'
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function resolveTarget() {
|
|
22
|
+
const arch = ARCH_MAP[os.arch()]
|
|
23
|
+
const osName = OS_MAP[os.platform()]
|
|
24
|
+
if (!arch) throw new Error(`Unsupported architecture: ${os.arch()}`)
|
|
25
|
+
if (!osName) throw new Error(`Unsupported platform: ${os.platform()}`)
|
|
26
|
+
return {arch, osName}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function buildUrl({arch, osName}) {
|
|
30
|
+
const JUNIE_VERSION = require("./package.json").junieVersion
|
|
31
|
+
const tag = `${JUNIE_VERSION}`
|
|
32
|
+
return `https://github.com/jetbrains-junie/junie/releases/download/${tag}/junie-cloud-eap.${JUNIE_VERSION}-${osName}-${arch}.zip`
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function stripQuarantine(targetPath) {
|
|
36
|
+
if (os.platform() !== 'darwin') return
|
|
37
|
+
try {
|
|
38
|
+
execSync(`xattr -dr com.apple.quarantine "${targetPath}"`, { stdio: 'ignore' })
|
|
39
|
+
} catch {
|
|
40
|
+
// ignore if xattr not available or attribute missing
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function chmodRecursive(dirPath) {
|
|
45
|
+
if (!fs.existsSync(dirPath)) return
|
|
46
|
+
const stack = [dirPath]
|
|
47
|
+
while (stack.length) {
|
|
48
|
+
const current = stack.pop()
|
|
49
|
+
let stat;
|
|
50
|
+
try {
|
|
51
|
+
stat = fs.lstatSync(current)
|
|
52
|
+
} catch {
|
|
53
|
+
continue
|
|
54
|
+
}
|
|
55
|
+
if (stat.isSymbolicLink()) continue;
|
|
56
|
+
if (stat.isDirectory()) {
|
|
57
|
+
try {
|
|
58
|
+
for (const entry of fs.readdirSync(current)) {
|
|
59
|
+
stack.push(path.join(current, entry))
|
|
60
|
+
}
|
|
61
|
+
} catch {
|
|
62
|
+
// ignore unreadable dirs
|
|
63
|
+
}
|
|
64
|
+
} else if (stat.isFile()) {
|
|
65
|
+
try {
|
|
66
|
+
fs.chmodSync(current, 0o755);
|
|
67
|
+
} catch {
|
|
68
|
+
// ignore files we can't chmod
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function downloadAndInstall() {
|
|
75
|
+
const {arch, osName} = resolveTarget()
|
|
76
|
+
const url = buildUrl({arch, osName})
|
|
77
|
+
const workDir = path.resolve(__dirname, 'bin', 'junie')
|
|
78
|
+
const markerFile = path.resolve(__dirname, 'bin', 'junie.download')
|
|
79
|
+
|
|
80
|
+
fs.mkdirSync(workDir, {recursive: true})
|
|
81
|
+
|
|
82
|
+
const zipPath = path.join(workDir, 'junie-runner.zip')
|
|
83
|
+
console.log(`[Junie] Downloading from ${url}`)
|
|
84
|
+
|
|
85
|
+
const res = await fetch(url)
|
|
86
|
+
if (!res.ok) throw new Error(`Download failed: ${res.status} ${res.statusText}`)
|
|
87
|
+
|
|
88
|
+
await pipeline(res.body, fs.createWriteStream(zipPath))
|
|
89
|
+
|
|
90
|
+
await fs.createReadStream(zipPath).pipe(unzipper.Extract({ path: workDir })).promise()
|
|
91
|
+
|
|
92
|
+
chmodRecursive(workDir)
|
|
93
|
+
stripQuarantine(workDir)
|
|
94
|
+
|
|
95
|
+
const binaryPath = getExpectedBinaryPath()
|
|
96
|
+
// Re-assert main binary is executable (cheap, idempotent)
|
|
97
|
+
try { fs.chmodSync(binaryPath, 0o755); } catch {}
|
|
98
|
+
|
|
99
|
+
fs.rmSync(zipPath)
|
|
100
|
+
|
|
101
|
+
fs.writeFileSync(markerFile, binaryPath, 'utf8')
|
|
102
|
+
|
|
103
|
+
console.log('[Junie] Installation complete.')
|
|
104
|
+
|
|
105
|
+
return binaryPath
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function main() {
|
|
109
|
+
try {
|
|
110
|
+
await downloadAndInstall()
|
|
111
|
+
} catch (error) {
|
|
112
|
+
console.error('[Junie] Post-install error:', error)
|
|
113
|
+
process.exit(1)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
main()
|