nexora-code 1.0.2 → 1.0.3
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/assets/icon.ico +0 -0
- package/assets/icon.png +0 -0
- package/dist/bundle.cjs +72428 -28941
- package/package.json +97 -84
- package/scripts/desktop/linux.cjs +126 -0
- package/scripts/desktop/macos.cjs +169 -0
- package/scripts/desktop/make-ico.ps1 +85 -0
- package/scripts/desktop/postinstall.cjs +40 -0
- package/scripts/desktop/preuninstall.cjs +29 -0
- package/scripts/desktop/shortcut.cjs +139 -0
- package/scripts/desktop/windows.cjs +99 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// ╔══════════════════════════════════════════════════════════════════════════════╗
|
|
3
|
+
// ║ Nexora Code — Desktop Shortcut Orchestrator ║
|
|
4
|
+
// ║ Handles context detection, routing, and cleanup across all platforms ║
|
|
5
|
+
// ╚══════════════════════════════════════════════════════════════════════════════╝
|
|
6
|
+
|
|
7
|
+
const os = require('os');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
|
|
11
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
function fileExistsSync(p) {
|
|
14
|
+
try { fs.accessSync(p); return true; } catch { return false; }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Finds the real home directory, even when running under sudo.
|
|
19
|
+
* On Linux/macOS: SUDO_USER env var tells us who actually invoked sudo.
|
|
20
|
+
* On Windows: USERPROFILE is always the actual user, even in admin shell.
|
|
21
|
+
*/
|
|
22
|
+
function getRealHomeDir() {
|
|
23
|
+
if (process.env.SUDO_USER) {
|
|
24
|
+
const plat = process.platform;
|
|
25
|
+
if (plat === 'linux') return `/home/${process.env.SUDO_USER}`;
|
|
26
|
+
if (plat === 'darwin') return `/Users/${process.env.SUDO_USER}`;
|
|
27
|
+
}
|
|
28
|
+
return process.env.USERPROFILE || process.env.HOME || os.homedir();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Finds the desktop path, trying multiple locale variants.
|
|
33
|
+
* Returns null if no desktop directory is found (headless/server/WSL).
|
|
34
|
+
*/
|
|
35
|
+
function findDesktopPath(homeDir, platform) {
|
|
36
|
+
const candidates = [];
|
|
37
|
+
|
|
38
|
+
if (platform === 'windows') {
|
|
39
|
+
candidates.push(
|
|
40
|
+
path.join(homeDir, 'Desktop'),
|
|
41
|
+
path.join(homeDir, 'OneDrive', 'Desktop'), // Very common on Win11 + OneDrive
|
|
42
|
+
path.join(homeDir, 'OneDrive - Personal', 'Desktop'),
|
|
43
|
+
);
|
|
44
|
+
} else if (platform === 'macos') {
|
|
45
|
+
candidates.push(path.join(homeDir, 'Desktop'));
|
|
46
|
+
} else {
|
|
47
|
+
// Linux: XDG standard + locale variants
|
|
48
|
+
const xdgDesktop = process.env.XDG_DESKTOP_DIR;
|
|
49
|
+
if (xdgDesktop) candidates.push(xdgDesktop);
|
|
50
|
+
candidates.push(
|
|
51
|
+
path.join(homeDir, 'Desktop'),
|
|
52
|
+
path.join(homeDir, 'Escritorio'), // Spanish
|
|
53
|
+
path.join(homeDir, 'Bureau'), // French
|
|
54
|
+
path.join(homeDir, 'Schreibtisch'), // German
|
|
55
|
+
path.join(homeDir, 'デスクトップ'), // Japanese
|
|
56
|
+
path.join(homeDir, '桌面'), // Chinese (Simplified)
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (const candidate of candidates) {
|
|
61
|
+
if (fileExistsSync(candidate)) return candidate;
|
|
62
|
+
}
|
|
63
|
+
return null; // No desktop (headless, WSL, server, etc.)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Resolves the package root directory.
|
|
68
|
+
* When postinstall runs, __dirname is scripts/desktop/ inside the package.
|
|
69
|
+
*/
|
|
70
|
+
function getPackageDir() {
|
|
71
|
+
// __dirname = <pkg>/scripts/desktop/
|
|
72
|
+
return path.resolve(__dirname, '..', '..');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Assembles all paths needed to create/remove shortcuts.
|
|
77
|
+
* @returns {{ platform, realHomeDir, desktopPath, packageDir, binaryPath, iconDir }}
|
|
78
|
+
*/
|
|
79
|
+
function buildUserContext() {
|
|
80
|
+
const rawPlatform = process.platform;
|
|
81
|
+
const platform =
|
|
82
|
+
rawPlatform === 'win32' ? 'windows' :
|
|
83
|
+
rawPlatform === 'darwin' ? 'macos' : 'linux';
|
|
84
|
+
|
|
85
|
+
const realHomeDir = getRealHomeDir();
|
|
86
|
+
const desktopPath = findDesktopPath(realHomeDir, platform);
|
|
87
|
+
const packageDir = getPackageDir();
|
|
88
|
+
const iconDir = path.join(packageDir, 'assets');
|
|
89
|
+
|
|
90
|
+
// Determine where npm placed the nexora-code binary
|
|
91
|
+
const binaryName = platform === 'windows' ? 'nexora-code.cmd' : 'nexora-code';
|
|
92
|
+
// npm puts global bins next to the node executable on Windows,
|
|
93
|
+
// or in /usr/local/bin (or prefix/bin) on Unix.
|
|
94
|
+
// process.execPath → e.g. C:\Program Files\nodejs\node.exe
|
|
95
|
+
// dirname → C:\Program Files\nodejs\ → that's where nexora-code.cmd lives
|
|
96
|
+
const npmBinDir = path.dirname(process.execPath);
|
|
97
|
+
const binaryPath = path.join(npmBinDir, binaryName);
|
|
98
|
+
|
|
99
|
+
return { platform, realHomeDir, desktopPath, packageDir, binaryPath, iconDir };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ── Public API ────────────────────────────────────────────────────────────────
|
|
103
|
+
|
|
104
|
+
function createShortcut() {
|
|
105
|
+
const ctx = buildUserContext();
|
|
106
|
+
|
|
107
|
+
if (!ctx.desktopPath) {
|
|
108
|
+
console.log(' ℹ No desktop found (headless / server / WSL environment).');
|
|
109
|
+
console.log(' Run "nexora-code" in any terminal to start.');
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
console.log('');
|
|
114
|
+
console.log(' ┌─────────────────────────────────────────────┐');
|
|
115
|
+
console.log(' │ Nexora Code — Desktop Shortcut Setup │');
|
|
116
|
+
console.log(' └─────────────────────────────────────────────┘');
|
|
117
|
+
console.log('');
|
|
118
|
+
|
|
119
|
+
switch (ctx.platform) {
|
|
120
|
+
case 'windows': require('./windows.cjs').createWindowsShortcut(ctx); break;
|
|
121
|
+
case 'macos': require('./macos.cjs').createMacosShortcut(ctx); break;
|
|
122
|
+
case 'linux': require('./linux.cjs').createLinuxShortcut(ctx); break;
|
|
123
|
+
default:
|
|
124
|
+
console.log(' ⚠ Unrecognised platform — skipping shortcut creation.');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function removeShortcut() {
|
|
129
|
+
const ctx = buildUserContext();
|
|
130
|
+
if (!ctx.desktopPath) return;
|
|
131
|
+
|
|
132
|
+
switch (ctx.platform) {
|
|
133
|
+
case 'windows': require('./windows.cjs').removeWindowsShortcut(ctx); break;
|
|
134
|
+
case 'macos': require('./macos.cjs').removeMacosShortcut(ctx); break;
|
|
135
|
+
case 'linux': require('./linux.cjs').removeLinuxShortcut(ctx); break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
module.exports = { createShortcut, removeShortcut, buildUserContext };
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// ╔══════════════════════════════════════════════════════════════════════════════╗
|
|
3
|
+
// ║ Nexora Code — Windows Shortcut Creator ║
|
|
4
|
+
// ║ Creates a .lnk file via PowerShell COM (WScript.Shell) — zero deps ║
|
|
5
|
+
// ╚══════════════════════════════════════════════════════════════════════════════╝
|
|
6
|
+
|
|
7
|
+
const { execSync } = require('child_process');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Detect the best available terminal on Windows.
|
|
13
|
+
* Priority: Windows Terminal > PowerShell 7 > PowerShell 5
|
|
14
|
+
*/
|
|
15
|
+
function detectWindowsTerminal() {
|
|
16
|
+
// Windows Terminal (wt.exe) — best colour/font support
|
|
17
|
+
try {
|
|
18
|
+
execSync('where wt.exe', { stdio: 'pipe' });
|
|
19
|
+
return {
|
|
20
|
+
exe: 'wt.exe',
|
|
21
|
+
args: 'nexora-code',
|
|
22
|
+
label: 'Windows Terminal',
|
|
23
|
+
};
|
|
24
|
+
} catch { /* not installed */ }
|
|
25
|
+
|
|
26
|
+
// PowerShell 7+ (pwsh.exe) — modern, cross-platform
|
|
27
|
+
try {
|
|
28
|
+
execSync('where pwsh.exe', { stdio: 'pipe' });
|
|
29
|
+
return {
|
|
30
|
+
exe: 'pwsh.exe',
|
|
31
|
+
args: '-NoExit -Command nexora-code',
|
|
32
|
+
label: 'PowerShell 7',
|
|
33
|
+
};
|
|
34
|
+
} catch { /* not installed */ }
|
|
35
|
+
|
|
36
|
+
// PowerShell 5 (built into all Windows 10/11) — guaranteed fallback
|
|
37
|
+
return {
|
|
38
|
+
exe: 'powershell.exe',
|
|
39
|
+
args: '-NoExit -Command nexora-code',
|
|
40
|
+
label: 'PowerShell 5 (built-in)',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Creates a Windows .lnk shortcut using PowerShell's WScript.Shell COM object.
|
|
46
|
+
* No external libraries required.
|
|
47
|
+
*/
|
|
48
|
+
function createWindowsShortcut(ctx) {
|
|
49
|
+
const shortcutPath = path.join(ctx.desktopPath, 'Nexora Code.lnk');
|
|
50
|
+
const iconPath = path.join(ctx.iconDir, 'icon.ico');
|
|
51
|
+
const iconExists = fs.existsSync(iconPath);
|
|
52
|
+
const terminal = detectWindowsTerminal();
|
|
53
|
+
|
|
54
|
+
// Escape single-quotes in paths for PowerShell string literals
|
|
55
|
+
const safeShortcutPath = shortcutPath.replace(/'/g, "''");
|
|
56
|
+
const safeIconPath = iconPath.replace(/'/g, "''");
|
|
57
|
+
const safeWorkingDir = '%USERPROFILE%';
|
|
58
|
+
|
|
59
|
+
const psLines = [
|
|
60
|
+
`$s = New-Object -ComObject WScript.Shell`,
|
|
61
|
+
`$lnk = $s.CreateShortcut('${safeShortcutPath}')`,
|
|
62
|
+
`$lnk.TargetPath = '${terminal.exe}'`,
|
|
63
|
+
`$lnk.Arguments = '${terminal.args}'`,
|
|
64
|
+
`$lnk.WorkingDirectory = '$env:USERPROFILE'`,
|
|
65
|
+
`$lnk.Description = 'Launch Nexora Code AI Workspace'`,
|
|
66
|
+
iconExists ? `$lnk.IconLocation = '${safeIconPath}'` : '',
|
|
67
|
+
`$lnk.Save()`,
|
|
68
|
+
].filter(Boolean).join('; ');
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
execSync(
|
|
72
|
+
`powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "${psLines}"`,
|
|
73
|
+
{ stdio: 'pipe', timeout: 20_000 }
|
|
74
|
+
);
|
|
75
|
+
console.log(` ✓ Shortcut created: ${shortcutPath}`);
|
|
76
|
+
console.log(` ✓ Opens with: ${terminal.label}`);
|
|
77
|
+
if (iconExists) console.log(` ✓ Icon applied: Nexora Code logo`);
|
|
78
|
+
console.log('');
|
|
79
|
+
console.log(' → Double-click "Nexora Code" on your Desktop to launch!');
|
|
80
|
+
console.log('');
|
|
81
|
+
} catch (err) {
|
|
82
|
+
throw new Error(`Windows .lnk creation failed: ${err.message}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Removes the Nexora Code desktop shortcut on Windows.
|
|
88
|
+
*/
|
|
89
|
+
function removeWindowsShortcut(ctx) {
|
|
90
|
+
const shortcutPath = path.join(ctx.desktopPath, 'Nexora Code.lnk');
|
|
91
|
+
try {
|
|
92
|
+
fs.unlinkSync(shortcutPath);
|
|
93
|
+
console.log(' ✓ Desktop shortcut removed: Nexora Code.lnk');
|
|
94
|
+
} catch {
|
|
95
|
+
// Already removed or never existed — that's fine
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
module.exports = { createWindowsShortcut, removeWindowsShortcut };
|