@jetbrains/junie-cli 0.1.0 → 0.1.2

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 (2) hide show
  1. package/package.json +2 -2
  2. package/postinstall.js +47 -8
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jetbrains/junie-cli",
3
- "version": "0.1.0",
4
- "junieVersion": "317.1",
3
+ "version": "0.1.2",
4
+ "junieVersion": "365.1",
5
5
  "description": "Junie command‑line client",
6
6
  "license": "SEE LICENSE IN LICENSE.md",
7
7
  "repository": "https://github.com/jetbrains-junie/junie",
package/postinstall.js CHANGED
@@ -33,6 +33,45 @@ function buildUrl({arch, osName}) {
33
33
  return `https://github.com/jetbrains-junie/junie/releases/download/${tag}/junie-cloud-eap-${JUNIE_IDE_VERSION}.${JUNIE_VERSION}-${osName}-${arch}.zip`
34
34
  }
35
35
 
36
+ function stripQuarantine(targetPath) {
37
+ if (os.platform() !== 'darwin') return
38
+ try {
39
+ execSync(`xattr -dr com.apple.quarantine "${targetPath}"`, { stdio: 'ignore' })
40
+ } catch {
41
+ // ignore if xattr not available or attribute missing
42
+ }
43
+ }
44
+
45
+ function chmodRecursive(dirPath) {
46
+ if (!fs.existsSync(dirPath)) return
47
+ const stack = [dirPath]
48
+ while (stack.length) {
49
+ const current = stack.pop()
50
+ let stat;
51
+ try {
52
+ stat = fs.lstatSync(current)
53
+ } catch {
54
+ continue
55
+ }
56
+ if (stat.isSymbolicLink()) continue;
57
+ if (stat.isDirectory()) {
58
+ try {
59
+ for (const entry of fs.readdirSync(current)) {
60
+ stack.push(path.join(current, entry))
61
+ }
62
+ } catch {
63
+ // ignore unreadable dirs
64
+ }
65
+ } else if (stat.isFile()) {
66
+ try {
67
+ fs.chmodSync(current, 0o755);
68
+ } catch {
69
+ // ignore files we can't chmod
70
+ }
71
+ }
72
+ }
73
+ }
74
+
36
75
  async function downloadAndInstall() {
37
76
  const {arch, osName} = resolveTarget()
38
77
  const url = buildUrl({arch, osName})
@@ -47,15 +86,16 @@ async function downloadAndInstall() {
47
86
  const res = await fetch(url)
48
87
  if (!res.ok) throw new Error(`Download failed: ${res.status} ${res.statusText}`)
49
88
 
50
- await pipeline(res.body, fs.createWriteStream(zipPath));
51
- console.log('[Junie] Downloaded, extracting…')
89
+ await pipeline(res.body, fs.createWriteStream(zipPath))
52
90
 
53
- await fs.createReadStream(zipPath)
54
- .pipe(unzipper.Extract({path: workDir}))
55
- .promise()
91
+ await fs.createReadStream(zipPath).pipe(unzipper.Extract({ path: workDir })).promise()
56
92
 
57
- const binaryPath = getExpectedBinaryPath();
58
- fs.chmodSync(binaryPath, 0o755)
93
+ chmodRecursive(workDir)
94
+ stripQuarantine(workDir)
95
+
96
+ const binaryPath = getExpectedBinaryPath()
97
+ // Re-assert main binary is executable (cheap, idempotent)
98
+ try { fs.chmodSync(binaryPath, 0o755); } catch {}
59
99
 
60
100
  fs.rmSync(zipPath)
61
101
 
@@ -66,7 +106,6 @@ async function downloadAndInstall() {
66
106
  return binaryPath
67
107
  }
68
108
 
69
-
70
109
  async function main() {
71
110
  try {
72
111
  await downloadAndInstall()