ropilot 0.1.4 → 0.1.6

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