ropilot 0.1.3 → 0.1.5

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/lib/setup.js +123 -7
  2. package/package.json +1 -1
package/lib/setup.js CHANGED
@@ -8,7 +8,7 @@
8
8
  * - Installing Studio plugin
9
9
  */
10
10
 
11
- import { existsSync, writeFileSync, mkdirSync, readFileSync } from 'fs';
11
+ import { existsSync, writeFileSync, mkdirSync, readFileSync, readdirSync } from 'fs';
12
12
  import { join, dirname } from 'path';
13
13
  import { homedir, platform } from 'os';
14
14
  import { createInterface } from 'readline';
@@ -28,17 +28,94 @@ const PLUGIN_VERSION_URL = 'https://ropilot.ai/plugin/version';
28
28
  const PLUGIN_DOWNLOAD_URL = 'https://ropilot.ai/plugin/StudioPlugin.lua';
29
29
 
30
30
  /**
31
- * Get Roblox plugins folder path based on OS
31
+ * Check if running in WSL
32
+ */
33
+ function isWSL() {
34
+ try {
35
+ const release = readFileSync('/proc/version', 'utf-8').toLowerCase();
36
+ return release.includes('microsoft') || release.includes('wsl');
37
+ } catch {
38
+ return false;
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Get Windows username when running in WSL (tries multiple methods)
44
+ */
45
+ function getWindowsUsername() {
46
+ const { execSync } = require('child_process');
47
+
48
+ // Method 1: cmd.exe
49
+ try {
50
+ const result = execSync('cmd.exe /c echo %USERNAME%', { encoding: 'utf-8', timeout: 5000 }).trim();
51
+ if (result && !result.includes('%')) return result;
52
+ } catch {}
53
+
54
+ // Method 2: whoami.exe (returns DOMAIN\user)
55
+ try {
56
+ const result = execSync('/mnt/c/Windows/System32/whoami.exe', { encoding: 'utf-8', timeout: 5000 }).trim();
57
+ if (result && result.includes('\\')) {
58
+ return result.split('\\').pop();
59
+ }
60
+ } catch {}
61
+
62
+ // Method 3: powershell
63
+ try {
64
+ const result = execSync('powershell.exe -NoProfile -Command "$env:USERNAME"', { encoding: 'utf-8', timeout: 5000 }).trim();
65
+ if (result) return result;
66
+ } catch {}
67
+
68
+ return null;
69
+ }
70
+
71
+ /**
72
+ * Get valid Windows users from /mnt/c/Users
73
+ */
74
+ function getValidWindowsUsers() {
75
+ const usersDir = '/mnt/c/Users';
76
+ try {
77
+ return readdirSync(usersDir).filter(u =>
78
+ !['Public', 'Default', 'Default User', 'All Users', 'desktop.ini'].includes(u) &&
79
+ existsSync(join(usersDir, u, 'AppData'))
80
+ );
81
+ } catch {
82
+ return [];
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Get Roblox plugins folder path based on OS (with WSL detection)
88
+ * Returns { path, needsPrompt, users } - needsPrompt true if user selection needed
32
89
  */
33
90
  function getPluginsFolder() {
34
91
  const os = platform();
92
+
93
+ // Check for WSL first - need to use Windows path
94
+ if (os === 'linux' && isWSL()) {
95
+ // Try to auto-detect Windows username
96
+ const windowsUser = getWindowsUsername();
97
+ if (windowsUser && existsSync(join('/mnt/c/Users', windowsUser))) {
98
+ return { path: join('/mnt/c/Users', windowsUser, 'AppData', 'Local', 'Roblox', 'Plugins') };
99
+ }
100
+
101
+ // Fallback: scan /mnt/c/Users
102
+ const validUsers = getValidWindowsUsers();
103
+ if (validUsers.length === 1) {
104
+ return { path: join('/mnt/c/Users', validUsers[0], 'AppData', 'Local', 'Roblox', 'Plugins') };
105
+ } else if (validUsers.length > 1) {
106
+ return { path: null, needsPrompt: true, users: validUsers };
107
+ }
108
+
109
+ return { path: null };
110
+ }
111
+
35
112
  if (os === 'win32') {
36
- return join(process.env.LOCALAPPDATA || join(homedir(), 'AppData', 'Local'), 'Roblox', 'Plugins');
113
+ return { path: join(process.env.LOCALAPPDATA || join(homedir(), 'AppData', 'Local'), 'Roblox', 'Plugins') };
37
114
  } else if (os === 'darwin') {
38
- return join(homedir(), 'Documents', 'Roblox', 'Plugins');
115
+ return { path: join(homedir(), 'Documents', 'Roblox', 'Plugins') };
39
116
  } else {
40
- // Linux - Roblox doesn't officially support Linux, but some use Wine
41
- return join(homedir(), '.local', 'share', 'Roblox', 'Plugins');
117
+ // Linux without WSL - Roblox doesn't officially support Linux
118
+ return { path: null };
42
119
  }
43
120
  }
44
121
 
@@ -82,7 +159,46 @@ async function installPlugin() {
82
159
  const pluginSource = await pluginResponse.text();
83
160
 
84
161
  // Get plugins folder
85
- const pluginsFolder = getPluginsFolder();
162
+ let folderResult = getPluginsFolder();
163
+ let pluginsFolder = folderResult.path;
164
+
165
+ // If WSL detected multiple users, prompt for selection
166
+ if (folderResult.needsPrompt && folderResult.users) {
167
+ console.log(' Multiple Windows users detected:');
168
+ folderResult.users.forEach((u, i) => console.log(` ${i + 1}. ${u}`));
169
+ const choice = await prompt(` Enter number (1-${folderResult.users.length}) or username: `);
170
+
171
+ let selectedUser;
172
+ const num = parseInt(choice);
173
+ if (num >= 1 && num <= folderResult.users.length) {
174
+ selectedUser = folderResult.users[num - 1];
175
+ } else if (folderResult.users.includes(choice)) {
176
+ selectedUser = choice;
177
+ } else if (existsSync(join('/mnt/c/Users', choice, 'AppData'))) {
178
+ selectedUser = choice;
179
+ }
180
+
181
+ if (selectedUser) {
182
+ pluginsFolder = join('/mnt/c/Users', selectedUser, 'AppData', 'Local', 'Roblox', 'Plugins');
183
+ }
184
+ }
185
+
186
+ // If still no folder and running in WSL, prompt for username directly
187
+ if (!pluginsFolder && isWSL()) {
188
+ const username = await prompt(' Enter your Windows username: ');
189
+ if (username && existsSync(join('/mnt/c/Users', username))) {
190
+ pluginsFolder = join('/mnt/c/Users', username, 'AppData', 'Local', 'Roblox', 'Plugins');
191
+ } else if (username) {
192
+ // Trust user input even if path doesn't exist yet
193
+ pluginsFolder = join('/mnt/c/Users', username, 'AppData', 'Local', 'Roblox', 'Plugins');
194
+ }
195
+ }
196
+
197
+ if (!pluginsFolder) {
198
+ console.log(' Could not determine Roblox plugins folder');
199
+ console.log(' Manual install: Download from https://ropilot.ai/plugin/StudioPlugin.lua');
200
+ return false;
201
+ }
86
202
 
87
203
  // Create plugins folder if it doesn't exist
88
204
  mkdirSync(pluginsFolder, { recursive: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ropilot",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "AI-powered Roblox development assistant - MCP CLI",
5
5
  "author": "whut",
6
6
  "license": "MIT",