antigravity-rtl-patcher 2.0.0 ā 2.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/README.md +22 -11
- package/bin/cli.js +10 -10
- package/package.json +2 -4
- package/payload/rtl-engine.js +334 -29
- package/payload/styles.css +200 -3
- package/src/patcher.js +12 -12
- package/src/paths.js +26 -11
package/README.md
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|

|
|
8
8
|

|
|
9
9
|
|
|
10
|
-
**Intelligent RTL & Persian Typography Engine for Antigravity
|
|
10
|
+
**Intelligent RTL & Persian Typography Engine for Antigravity**
|
|
11
11
|
|
|
12
|
-
*One command. Full right-to-left support.
|
|
12
|
+
*One command. Full right-to-left support. Toggle on/off anytime.*
|
|
13
13
|
|
|
14
14
|
</div>
|
|
15
15
|
|
|
@@ -17,13 +17,14 @@
|
|
|
17
17
|
|
|
18
18
|
## 𧬠How It Works
|
|
19
19
|
|
|
20
|
-
Antigravity
|
|
20
|
+
Antigravity is built on Electron. This CLI tool directly patches the app's core workbench files to inject a smart **MutationObserver** engine that:
|
|
21
21
|
|
|
22
22
|
1. š **Watches** the DOM for new chat messages and AI responses in real-time
|
|
23
23
|
2. š§ **Detects** Persian/Arabic/Hebrew text using Unicode analysis with ratio-based scoring
|
|
24
24
|
3. šØ **Applies** `direction: rtl` and `unicode-bidi: plaintext` only where needed
|
|
25
25
|
4. āļø **Injects** the beautiful **Vazirmatn** font for perfect Persian/Arabic readability
|
|
26
26
|
5. š **Isolates** English code blocks inside RTL text so they don't break
|
|
27
|
+
6. šļø **Toggle Panel** ā Enable/disable RTL support anytime via the in-app panel
|
|
27
28
|
|
|
28
29
|
---
|
|
29
30
|
|
|
@@ -42,7 +43,17 @@ sudo npx antigravity-rtl-patcher patch
|
|
|
42
43
|
npx antigravity-rtl-patcher patch
|
|
43
44
|
```
|
|
44
45
|
|
|
45
|
-
That's it. Restart Antigravity
|
|
46
|
+
That's it. Restart Antigravity and enjoy native RTL support. āØ
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## šļø In-App Toggle
|
|
51
|
+
|
|
52
|
+
After patching, a small **RTL icon** appears at the bottom of Antigravity's status bar. Click it to open the settings panel:
|
|
53
|
+
|
|
54
|
+
- **Enabled** ā Toggle RTL support on/off instantly
|
|
55
|
+
- Settings are saved automatically and persist across restarts
|
|
56
|
+
- Works on every page ā enable/disable applies everywhere
|
|
46
57
|
|
|
47
58
|
---
|
|
48
59
|
|
|
@@ -50,16 +61,16 @@ That's it. Restart Antigravity IDE and enjoy native RTL support. āØ
|
|
|
50
61
|
|
|
51
62
|
| Command | Description |
|
|
52
63
|
|---------|-------------|
|
|
53
|
-
| `agy-rtl patch` | Inject RTL support into Antigravity
|
|
64
|
+
| `agy-rtl patch` | Inject RTL support into Antigravity |
|
|
54
65
|
| `agy-rtl restore` | Remove patch and restore original files |
|
|
55
|
-
| `agy-rtl status` | Check if
|
|
66
|
+
| `agy-rtl status` | Check if Antigravity is currently patched |
|
|
56
67
|
| `agy-rtl patch --path /custom/path` | Patch a custom installation directory |
|
|
57
68
|
|
|
58
69
|
---
|
|
59
70
|
|
|
60
|
-
## š After
|
|
71
|
+
## š After Updates
|
|
61
72
|
|
|
62
|
-
When Antigravity
|
|
73
|
+
When Antigravity updates, the patch may be overwritten. Simply run the patch command again:
|
|
63
74
|
|
|
64
75
|
```bash
|
|
65
76
|
npx antigravity-rtl-patcher patch
|
|
@@ -78,8 +89,8 @@ antigravity-rtl-patcher/
|
|
|
78
89
|
ā āāā paths.js # OS-aware installation path detection
|
|
79
90
|
ā āāā utils.js # Permission checks & helpers
|
|
80
91
|
āāā payload/
|
|
81
|
-
ā āāā rtl-engine.js # MutationObserver RTL
|
|
82
|
-
ā āāā styles.css # Vazirmatn font + RTL
|
|
92
|
+
ā āāā rtl-engine.js # MutationObserver RTL engine + Toggle UI
|
|
93
|
+
ā āāā styles.css # Vazirmatn font + RTL + Panel styles
|
|
83
94
|
āāā package.json
|
|
84
95
|
āāā README.md
|
|
85
96
|
```
|
|
@@ -88,7 +99,7 @@ antigravity-rtl-patcher/
|
|
|
88
99
|
|
|
89
100
|
| Type | Description | Method |
|
|
90
101
|
|------|-------------|--------|
|
|
91
|
-
| **Unpacked** |
|
|
102
|
+
| **Unpacked** | App with `resources/app/` directory | Direct file modification |
|
|
92
103
|
| **ASAR** | App bundled as `app.asar` | Extract ā Patch ā Repack |
|
|
93
104
|
|
|
94
105
|
---
|
package/bin/cli.js
CHANGED
|
@@ -6,20 +6,20 @@ const { patch, restore, status } = require('../src/patcher');
|
|
|
6
6
|
|
|
7
7
|
const BANNER = `
|
|
8
8
|
${chalk.cyan('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā')}
|
|
9
|
-
${chalk.cyan('ā')} ${chalk.bold.white('š Antigravity RTL Patcher')} ${chalk.gray('v2.
|
|
10
|
-
${chalk.cyan('ā')} ${chalk.gray('Intelligent RTL support for Antigravity
|
|
9
|
+
${chalk.cyan('ā')} ${chalk.bold.white('š Antigravity RTL Patcher')} ${chalk.gray('v2.1.0')} ${chalk.cyan('ā')}
|
|
10
|
+
${chalk.cyan('ā')} ${chalk.gray('Intelligent RTL support for Antigravity')} ${chalk.cyan('ā')}
|
|
11
11
|
${chalk.cyan('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā')}
|
|
12
12
|
`;
|
|
13
13
|
|
|
14
14
|
program
|
|
15
15
|
.name('agy-rtl')
|
|
16
|
-
.description('RTL & Typography patcher for Antigravity
|
|
17
|
-
.version('2.
|
|
16
|
+
.description('RTL & Typography patcher for Antigravity')
|
|
17
|
+
.version('2.1.0');
|
|
18
18
|
|
|
19
19
|
program
|
|
20
20
|
.command('patch')
|
|
21
|
-
.description('Inject RTL support into Antigravity
|
|
22
|
-
.option('-p, --path <path>', 'Custom path to Antigravity
|
|
21
|
+
.description('Inject RTL support into Antigravity')
|
|
22
|
+
.option('-p, --path <path>', 'Custom path to Antigravity installation')
|
|
23
23
|
.action(async (options) => {
|
|
24
24
|
console.log(BANNER);
|
|
25
25
|
try {
|
|
@@ -32,8 +32,8 @@ program
|
|
|
32
32
|
|
|
33
33
|
program
|
|
34
34
|
.command('restore')
|
|
35
|
-
.description('Restore Antigravity
|
|
36
|
-
.option('-p, --path <path>', 'Custom path to Antigravity
|
|
35
|
+
.description('Restore Antigravity to its original state')
|
|
36
|
+
.option('-p, --path <path>', 'Custom path to Antigravity installation')
|
|
37
37
|
.action(async (options) => {
|
|
38
38
|
console.log(BANNER);
|
|
39
39
|
try {
|
|
@@ -46,8 +46,8 @@ program
|
|
|
46
46
|
|
|
47
47
|
program
|
|
48
48
|
.command('status')
|
|
49
|
-
.description('Check if Antigravity
|
|
50
|
-
.option('-p, --path <path>', 'Custom path to Antigravity
|
|
49
|
+
.description('Check if Antigravity is currently patched')
|
|
50
|
+
.option('-p, --path <path>', 'Custom path to Antigravity installation')
|
|
51
51
|
.action(async (options) => {
|
|
52
52
|
console.log(BANNER);
|
|
53
53
|
try {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "antigravity-rtl-patcher",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "š Intelligent RTL & Persian/Arabic typography patcher for Antigravity
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "š Intelligent RTL & Persian/Arabic typography patcher for Antigravity",
|
|
5
5
|
"main": "src/patcher.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"antigravity-rtl-patcher": "./bin/cli.js",
|
|
@@ -22,8 +22,6 @@
|
|
|
22
22
|
"patcher",
|
|
23
23
|
"electron",
|
|
24
24
|
"asar",
|
|
25
|
-
"ide",
|
|
26
|
-
"vscode",
|
|
27
25
|
"right-to-left",
|
|
28
26
|
"bidirectional"
|
|
29
27
|
],
|
package/payload/rtl-engine.js
CHANGED
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AGY RTL Engine v2.
|
|
3
|
-
* Intelligent RTL detection & styling for Antigravity
|
|
4
|
-
*
|
|
2
|
+
* AGY RTL Engine v2.1.0
|
|
3
|
+
* Intelligent RTL detection & styling for Antigravity
|
|
4
|
+
*
|
|
5
5
|
* This script runs inside the Electron renderer process.
|
|
6
6
|
* It uses MutationObserver to watch for DOM changes and
|
|
7
7
|
* automatically applies RTL direction to Persian/Arabic/Hebrew text.
|
|
8
|
-
*
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - Toggle panel UI with Enable/Disable switch
|
|
11
|
+
* - Persistent state via localStorage
|
|
12
|
+
* - Real-time apply/remove across all pages
|
|
13
|
+
*
|
|
9
14
|
* CSP Compatible: No use of innerHTML, eval, or inline event handlers.
|
|
10
15
|
*/
|
|
11
16
|
(function () {
|
|
12
17
|
'use strict';
|
|
13
18
|
|
|
19
|
+
// āāā Configuration āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
20
|
+
const STORAGE_KEY = 'agy-rtl-enabled';
|
|
21
|
+
const PANEL_ID = 'agy-rtl-panel';
|
|
22
|
+
const TOGGLE_BTN_ID = 'agy-rtl-toggle-btn';
|
|
23
|
+
const STATUS_ICON_ID = 'agy-rtl-status-icon';
|
|
24
|
+
const GITHUB_URL = 'https://github.com/VaFa1726/antigravity-rtl-patcher';
|
|
25
|
+
|
|
14
26
|
// Unicode ranges for RTL scripts
|
|
15
27
|
const RTL_REGEX = /[\u0591-\u07FF\u200F\u202B\u202E\uFB1D-\uFDFD\uFE70-\uFEFC]/;
|
|
16
|
-
|
|
17
|
-
// Minimum ratio of RTL characters to consider text as RTL
|
|
18
28
|
const RTL_CHAR_REGEX = /[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]/g;
|
|
19
29
|
const MIN_RTL_RATIO = 0.3;
|
|
20
30
|
|
|
@@ -54,20 +64,42 @@
|
|
|
54
64
|
'p', 'li', 'h1', 'h2', 'h3', 'h4', 'blockquote',
|
|
55
65
|
].join(', ');
|
|
56
66
|
|
|
67
|
+
// āāā State āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
68
|
+
var isEnabled = getStoredState();
|
|
69
|
+
var observer = null;
|
|
70
|
+
var panelVisible = false;
|
|
71
|
+
|
|
72
|
+
// āāā Helpers āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
73
|
+
|
|
74
|
+
function getStoredState() {
|
|
75
|
+
try {
|
|
76
|
+
var stored = localStorage.getItem(STORAGE_KEY);
|
|
77
|
+
if (stored === null) return true; // Default: enabled
|
|
78
|
+
return stored === 'true';
|
|
79
|
+
} catch (e) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function setStoredState(val) {
|
|
85
|
+
try {
|
|
86
|
+
localStorage.setItem(STORAGE_KEY, val ? 'true' : 'false');
|
|
87
|
+
} catch (e) {
|
|
88
|
+
// Ignore storage errors
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
57
92
|
/**
|
|
58
93
|
* Determine if a text string is primarily RTL.
|
|
59
94
|
*/
|
|
60
95
|
function isRTL(text) {
|
|
61
96
|
if (!text || text.trim().length === 0) return false;
|
|
62
|
-
|
|
63
|
-
// Quick check: does it contain any RTL character at all?
|
|
64
97
|
if (!RTL_REGEX.test(text)) return false;
|
|
65
98
|
|
|
66
|
-
|
|
67
|
-
const rtlMatches = text.match(RTL_CHAR_REGEX);
|
|
99
|
+
var rtlMatches = text.match(RTL_CHAR_REGEX);
|
|
68
100
|
if (!rtlMatches) return false;
|
|
69
101
|
|
|
70
|
-
|
|
102
|
+
var alphaChars = text.replace(/[\s\d\W]/g, '').length;
|
|
71
103
|
if (alphaChars === 0) return false;
|
|
72
104
|
|
|
73
105
|
return (rtlMatches.length / alphaChars) >= MIN_RTL_RATIO;
|
|
@@ -79,7 +111,7 @@
|
|
|
79
111
|
function applyRTL(element) {
|
|
80
112
|
if (element.getAttribute(PROCESSED_ATTR)) return;
|
|
81
113
|
|
|
82
|
-
|
|
114
|
+
var text = element.textContent || '';
|
|
83
115
|
if (isRTL(text)) {
|
|
84
116
|
element.setAttribute(PROCESSED_ATTR, 'true');
|
|
85
117
|
element.style.direction = 'rtl';
|
|
@@ -88,46 +120,65 @@
|
|
|
88
120
|
}
|
|
89
121
|
}
|
|
90
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Remove RTL styling from an element.
|
|
125
|
+
*/
|
|
126
|
+
function removeRTL(element) {
|
|
127
|
+
if (element.getAttribute(PROCESSED_ATTR)) {
|
|
128
|
+
element.removeAttribute(PROCESSED_ATTR);
|
|
129
|
+
element.style.direction = '';
|
|
130
|
+
element.style.textAlign = '';
|
|
131
|
+
element.style.unicodeBidi = '';
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
91
135
|
/**
|
|
92
136
|
* Scan a subtree for elements that need RTL.
|
|
93
137
|
*/
|
|
94
138
|
function scanElement(root) {
|
|
95
139
|
if (!root || root.nodeType !== Node.ELEMENT_NODE) return;
|
|
96
140
|
|
|
97
|
-
// Check if the root itself matches
|
|
98
141
|
try {
|
|
99
142
|
if (root.matches && root.matches(TARGET_SELECTORS)) {
|
|
100
143
|
applyRTL(root);
|
|
101
144
|
}
|
|
102
|
-
} catch (e) {
|
|
103
|
-
// Ignore selector errors
|
|
104
|
-
}
|
|
145
|
+
} catch (e) { /* Ignore */ }
|
|
105
146
|
|
|
106
|
-
// Scan children
|
|
107
147
|
try {
|
|
108
|
-
|
|
148
|
+
var elements = root.querySelectorAll(TARGET_SELECTORS);
|
|
109
149
|
elements.forEach(function (el) {
|
|
110
150
|
applyRTL(el);
|
|
111
151
|
});
|
|
112
|
-
} catch (e) {
|
|
113
|
-
// Ignore errors
|
|
114
|
-
}
|
|
152
|
+
} catch (e) { /* Ignore */ }
|
|
115
153
|
}
|
|
116
154
|
|
|
117
155
|
/**
|
|
118
|
-
*
|
|
156
|
+
* Remove RTL from all processed elements.
|
|
119
157
|
*/
|
|
120
|
-
function
|
|
121
|
-
|
|
158
|
+
function clearAllRTL() {
|
|
159
|
+
try {
|
|
160
|
+
var elements = document.querySelectorAll('[' + PROCESSED_ATTR + ']');
|
|
161
|
+
elements.forEach(function (el) {
|
|
162
|
+
removeRTL(el);
|
|
163
|
+
});
|
|
164
|
+
} catch (e) { /* Ignore */ }
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// āāā MutationObserver āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
168
|
+
|
|
169
|
+
function startObserver() {
|
|
170
|
+
if (observer) return;
|
|
171
|
+
|
|
172
|
+
observer = new MutationObserver(function (mutations) {
|
|
173
|
+
if (!isEnabled) return;
|
|
174
|
+
|
|
122
175
|
mutations.forEach(function (mutation) {
|
|
123
|
-
// Handle added nodes
|
|
124
176
|
mutation.addedNodes.forEach(function (node) {
|
|
125
177
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
126
178
|
scanElement(node);
|
|
127
179
|
}
|
|
128
180
|
});
|
|
129
181
|
|
|
130
|
-
// Handle text content changes
|
|
131
182
|
if (mutation.type === 'characterData' && mutation.target.parentElement) {
|
|
132
183
|
applyRTL(mutation.target.parentElement);
|
|
133
184
|
}
|
|
@@ -144,13 +195,267 @@
|
|
|
144
195
|
scanElement(document.body);
|
|
145
196
|
}
|
|
146
197
|
|
|
198
|
+
function stopObserver() {
|
|
199
|
+
if (observer) {
|
|
200
|
+
observer.disconnect();
|
|
201
|
+
observer = null;
|
|
202
|
+
}
|
|
203
|
+
clearAllRTL();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// āāā Toggle Panel UI āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
207
|
+
|
|
208
|
+
function createStatusIcon() {
|
|
209
|
+
// Check if icon already exists
|
|
210
|
+
if (document.getElementById(STATUS_ICON_ID)) return;
|
|
211
|
+
|
|
212
|
+
var icon = document.createElement('div');
|
|
213
|
+
icon.id = STATUS_ICON_ID;
|
|
214
|
+
icon.className = 'agy-rtl-status-icon';
|
|
215
|
+
icon.setAttribute('role', 'button');
|
|
216
|
+
icon.setAttribute('tabindex', '0');
|
|
217
|
+
icon.setAttribute('title', 'Antigravity Smart RTL');
|
|
218
|
+
|
|
219
|
+
// RTL icon SVG
|
|
220
|
+
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
221
|
+
svg.setAttribute('width', '16');
|
|
222
|
+
svg.setAttribute('height', '16');
|
|
223
|
+
svg.setAttribute('viewBox', '0 0 24 24');
|
|
224
|
+
svg.setAttribute('fill', 'none');
|
|
225
|
+
svg.setAttribute('stroke', 'currentColor');
|
|
226
|
+
svg.setAttribute('stroke-width', '2');
|
|
227
|
+
svg.setAttribute('stroke-linecap', 'round');
|
|
228
|
+
svg.setAttribute('stroke-linejoin', 'round');
|
|
229
|
+
|
|
230
|
+
// Pilcrow/RTL icon path
|
|
231
|
+
var path1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
232
|
+
path1.setAttribute('d', 'M16 4H9.5a3.5 3.5 0 1 0 0 7H12');
|
|
233
|
+
svg.appendChild(path1);
|
|
234
|
+
|
|
235
|
+
var path2 = document.createElementNS('http://www.w3.org/2000/svg', 'line');
|
|
236
|
+
path2.setAttribute('x1', '12');
|
|
237
|
+
path2.setAttribute('y1', '4');
|
|
238
|
+
path2.setAttribute('x2', '12');
|
|
239
|
+
path2.setAttribute('y2', '20');
|
|
240
|
+
svg.appendChild(path2);
|
|
241
|
+
|
|
242
|
+
var path3 = document.createElementNS('http://www.w3.org/2000/svg', 'line');
|
|
243
|
+
path3.setAttribute('x1', '16');
|
|
244
|
+
path3.setAttribute('y1', '4');
|
|
245
|
+
path3.setAttribute('x2', '16');
|
|
246
|
+
path3.setAttribute('y2', '20');
|
|
247
|
+
svg.appendChild(path3);
|
|
248
|
+
|
|
249
|
+
icon.appendChild(svg);
|
|
250
|
+
|
|
251
|
+
// Status dot
|
|
252
|
+
var dot = document.createElement('span');
|
|
253
|
+
dot.className = 'agy-rtl-status-dot';
|
|
254
|
+
if (isEnabled) dot.classList.add('active');
|
|
255
|
+
icon.appendChild(dot);
|
|
256
|
+
|
|
257
|
+
icon.addEventListener('click', function (e) {
|
|
258
|
+
e.stopPropagation();
|
|
259
|
+
togglePanel();
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
icon.addEventListener('keydown', function (e) {
|
|
263
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
264
|
+
e.preventDefault();
|
|
265
|
+
e.stopPropagation();
|
|
266
|
+
togglePanel();
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// Try to insert into the status bar, fallback to body
|
|
271
|
+
var statusBar = document.querySelector('.statusbar-item.right') ||
|
|
272
|
+
document.querySelector('.statusbar') ||
|
|
273
|
+
document.querySelector('[id*="statusbar"]') ||
|
|
274
|
+
document.querySelector('.footer') ||
|
|
275
|
+
document.body;
|
|
276
|
+
|
|
277
|
+
if (statusBar === document.body) {
|
|
278
|
+
// Position fixed at bottom-right
|
|
279
|
+
icon.classList.add('agy-rtl-fixed');
|
|
280
|
+
document.body.appendChild(icon);
|
|
281
|
+
} else {
|
|
282
|
+
statusBar.appendChild(icon);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function createPanel() {
|
|
287
|
+
if (document.getElementById(PANEL_ID)) return;
|
|
288
|
+
|
|
289
|
+
var panel = document.createElement('div');
|
|
290
|
+
panel.id = PANEL_ID;
|
|
291
|
+
panel.className = 'agy-rtl-panel';
|
|
292
|
+
|
|
293
|
+
// āā Header āā
|
|
294
|
+
var header = document.createElement('div');
|
|
295
|
+
header.className = 'agy-rtl-panel-header';
|
|
296
|
+
|
|
297
|
+
var title = document.createElement('span');
|
|
298
|
+
title.className = 'agy-rtl-panel-title';
|
|
299
|
+
title.textContent = 'Antigravity Smart RTL';
|
|
300
|
+
header.appendChild(title);
|
|
301
|
+
panel.appendChild(header);
|
|
302
|
+
|
|
303
|
+
// āā Toggle Row āā
|
|
304
|
+
var row = document.createElement('div');
|
|
305
|
+
row.className = 'agy-rtl-panel-row';
|
|
306
|
+
|
|
307
|
+
var label = document.createElement('span');
|
|
308
|
+
label.className = 'agy-rtl-panel-label';
|
|
309
|
+
label.textContent = 'Enabled';
|
|
310
|
+
row.appendChild(label);
|
|
311
|
+
|
|
312
|
+
var toggleWrapper = document.createElement('label');
|
|
313
|
+
toggleWrapper.className = 'agy-rtl-switch';
|
|
314
|
+
|
|
315
|
+
var checkbox = document.createElement('input');
|
|
316
|
+
checkbox.type = 'checkbox';
|
|
317
|
+
checkbox.id = TOGGLE_BTN_ID;
|
|
318
|
+
checkbox.checked = isEnabled;
|
|
319
|
+
|
|
320
|
+
var slider = document.createElement('span');
|
|
321
|
+
slider.className = 'agy-rtl-slider';
|
|
322
|
+
|
|
323
|
+
toggleWrapper.appendChild(checkbox);
|
|
324
|
+
toggleWrapper.appendChild(slider);
|
|
325
|
+
row.appendChild(toggleWrapper);
|
|
326
|
+
panel.appendChild(row);
|
|
327
|
+
|
|
328
|
+
// āā Separator āā
|
|
329
|
+
var sep = document.createElement('div');
|
|
330
|
+
sep.className = 'agy-rtl-panel-sep';
|
|
331
|
+
panel.appendChild(sep);
|
|
332
|
+
|
|
333
|
+
// āā GitHub Link āā
|
|
334
|
+
var ghRow = document.createElement('div');
|
|
335
|
+
ghRow.className = 'agy-rtl-panel-row agy-rtl-panel-gh';
|
|
336
|
+
|
|
337
|
+
var ghLink = document.createElement('a');
|
|
338
|
+
ghLink.className = 'agy-rtl-gh-link';
|
|
339
|
+
ghLink.href = GITHUB_URL;
|
|
340
|
+
ghLink.target = '_blank';
|
|
341
|
+
ghLink.rel = 'noopener noreferrer';
|
|
342
|
+
|
|
343
|
+
// GitHub icon SVG
|
|
344
|
+
var ghSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
345
|
+
ghSvg.setAttribute('width', '14');
|
|
346
|
+
ghSvg.setAttribute('height', '14');
|
|
347
|
+
ghSvg.setAttribute('viewBox', '0 0 16 16');
|
|
348
|
+
ghSvg.setAttribute('fill', 'currentColor');
|
|
349
|
+
|
|
350
|
+
var ghPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
351
|
+
ghPath.setAttribute('d', 'M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z');
|
|
352
|
+
ghSvg.appendChild(ghPath);
|
|
353
|
+
ghLink.appendChild(ghSvg);
|
|
354
|
+
|
|
355
|
+
var ghText = document.createElement('span');
|
|
356
|
+
ghText.textContent = ' Star on GitHub';
|
|
357
|
+
ghLink.appendChild(ghText);
|
|
358
|
+
|
|
359
|
+
ghRow.appendChild(ghLink);
|
|
360
|
+
panel.appendChild(ghRow);
|
|
361
|
+
|
|
362
|
+
// āā Event Handlers āā
|
|
363
|
+
checkbox.addEventListener('change', function () {
|
|
364
|
+
isEnabled = checkbox.checked;
|
|
365
|
+
setStoredState(isEnabled);
|
|
366
|
+
updateState();
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
// Close panel when clicking outside
|
|
370
|
+
document.addEventListener('click', function (e) {
|
|
371
|
+
var panelEl = document.getElementById(PANEL_ID);
|
|
372
|
+
var iconEl = document.getElementById(STATUS_ICON_ID);
|
|
373
|
+
if (panelEl && panelVisible && !panelEl.contains(e.target) && !iconEl.contains(e.target)) {
|
|
374
|
+
hidePanel();
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
document.body.appendChild(panel);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
function togglePanel() {
|
|
382
|
+
if (panelVisible) {
|
|
383
|
+
hidePanel();
|
|
384
|
+
} else {
|
|
385
|
+
showPanel();
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function showPanel() {
|
|
390
|
+
var panel = document.getElementById(PANEL_ID);
|
|
391
|
+
if (!panel) {
|
|
392
|
+
createPanel();
|
|
393
|
+
panel = document.getElementById(PANEL_ID);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Position the panel above the icon
|
|
397
|
+
var icon = document.getElementById(STATUS_ICON_ID);
|
|
398
|
+
if (icon) {
|
|
399
|
+
var iconRect = icon.getBoundingClientRect();
|
|
400
|
+
panel.style.bottom = (window.innerHeight - iconRect.top + 8) + 'px';
|
|
401
|
+
panel.style.right = (window.innerWidth - iconRect.right) + 'px';
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
panel.classList.add('visible');
|
|
405
|
+
panelVisible = true;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function hidePanel() {
|
|
409
|
+
var panel = document.getElementById(PANEL_ID);
|
|
410
|
+
if (panel) {
|
|
411
|
+
panel.classList.remove('visible');
|
|
412
|
+
}
|
|
413
|
+
panelVisible = false;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Update the UI and RTL state based on isEnabled.
|
|
418
|
+
*/
|
|
419
|
+
function updateState() {
|
|
420
|
+
// Update status dot
|
|
421
|
+
var dot = document.querySelector('.agy-rtl-status-dot');
|
|
422
|
+
if (dot) {
|
|
423
|
+
if (isEnabled) {
|
|
424
|
+
dot.classList.add('active');
|
|
425
|
+
} else {
|
|
426
|
+
dot.classList.remove('active');
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// Update toggle checkbox
|
|
431
|
+
var checkbox = document.getElementById(TOGGLE_BTN_ID);
|
|
432
|
+
if (checkbox) {
|
|
433
|
+
checkbox.checked = isEnabled;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Apply or remove RTL
|
|
437
|
+
if (isEnabled) {
|
|
438
|
+
startObserver();
|
|
439
|
+
} else {
|
|
440
|
+
stopObserver();
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// āāā Initialization āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
445
|
+
|
|
446
|
+
function init() {
|
|
447
|
+
createStatusIcon();
|
|
448
|
+
createPanel();
|
|
449
|
+
updateState();
|
|
450
|
+
}
|
|
451
|
+
|
|
147
452
|
// Start when DOM is ready
|
|
148
453
|
if (document.readyState === 'loading') {
|
|
149
|
-
document.addEventListener('DOMContentLoaded',
|
|
454
|
+
document.addEventListener('DOMContentLoaded', init);
|
|
150
455
|
} else {
|
|
151
456
|
// DOM already loaded, wait a moment for dynamic content
|
|
152
|
-
setTimeout(
|
|
457
|
+
setTimeout(init, 500);
|
|
153
458
|
}
|
|
154
459
|
|
|
155
|
-
console.log('%cš AGY RTL Engine v2.
|
|
460
|
+
console.log('%cš AGY RTL Engine v2.1.0 loaded', 'color: cyan; font-weight: bold;');
|
|
156
461
|
})();
|
package/payload/styles.css
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* AGY RTL Styles v2.
|
|
3
|
-
* Typography & RTL fixes for Antigravity
|
|
2
|
+
* AGY RTL Styles v2.1.0
|
|
3
|
+
* Typography & RTL fixes + Toggle Panel for Antigravity
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
/* Vazirmatn ā Modern Persian/Arabic font from Google Fonts */
|
|
7
7
|
@import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;700&display=swap');
|
|
8
8
|
|
|
9
|
-
/* RTL
|
|
9
|
+
/* āāā RTL Text Styling āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā */
|
|
10
|
+
|
|
10
11
|
[data-agy-rtl="true"] {
|
|
11
12
|
font-family: 'Vazirmatn', system-ui, -apple-system, 'Segoe UI', sans-serif !important;
|
|
12
13
|
line-height: 1.85 !important;
|
|
@@ -35,3 +36,199 @@
|
|
|
35
36
|
[data-agy-rtl="true"] li {
|
|
36
37
|
list-style-position: inside;
|
|
37
38
|
}
|
|
39
|
+
|
|
40
|
+
/* āāā Status Bar Icon āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā */
|
|
41
|
+
|
|
42
|
+
.agy-rtl-status-icon {
|
|
43
|
+
display: inline-flex;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: center;
|
|
46
|
+
position: relative;
|
|
47
|
+
width: 28px;
|
|
48
|
+
height: 22px;
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
color: var(--vscode-statusBar-foreground, #ccc);
|
|
51
|
+
opacity: 0.85;
|
|
52
|
+
transition: opacity 0.2s ease, color 0.2s ease;
|
|
53
|
+
vertical-align: middle;
|
|
54
|
+
border-radius: 3px;
|
|
55
|
+
user-select: none;
|
|
56
|
+
-webkit-user-select: none;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.agy-rtl-status-icon:hover {
|
|
60
|
+
opacity: 1;
|
|
61
|
+
color: var(--vscode-statusBarItem-hoverForeground, #fff);
|
|
62
|
+
background: var(--vscode-statusBarItem-hoverBackground, rgba(255,255,255,0.12));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Fixed position fallback when status bar not found */
|
|
66
|
+
.agy-rtl-status-icon.agy-rtl-fixed {
|
|
67
|
+
position: fixed;
|
|
68
|
+
bottom: 0;
|
|
69
|
+
right: 100px;
|
|
70
|
+
z-index: 99999;
|
|
71
|
+
width: 32px;
|
|
72
|
+
height: 22px;
|
|
73
|
+
background: var(--vscode-statusBar-background, #007acc);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* Status dot indicator */
|
|
77
|
+
.agy-rtl-status-dot {
|
|
78
|
+
position: absolute;
|
|
79
|
+
top: 2px;
|
|
80
|
+
right: 2px;
|
|
81
|
+
width: 6px;
|
|
82
|
+
height: 6px;
|
|
83
|
+
border-radius: 50%;
|
|
84
|
+
background: #666;
|
|
85
|
+
transition: background 0.3s ease, box-shadow 0.3s ease;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.agy-rtl-status-dot.active {
|
|
89
|
+
background: #4caf50;
|
|
90
|
+
box-shadow: 0 0 4px rgba(76, 175, 80, 0.6);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* āāā Toggle Panel āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā */
|
|
94
|
+
|
|
95
|
+
.agy-rtl-panel {
|
|
96
|
+
position: fixed;
|
|
97
|
+
z-index: 100000;
|
|
98
|
+
min-width: 260px;
|
|
99
|
+
max-width: 300px;
|
|
100
|
+
background: var(--vscode-editorWidget-background, #252526);
|
|
101
|
+
border: 1px solid var(--vscode-editorWidget-border, #454545);
|
|
102
|
+
border-radius: 8px;
|
|
103
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.45), 0 2px 8px rgba(0, 0, 0, 0.2);
|
|
104
|
+
padding: 16px;
|
|
105
|
+
opacity: 0;
|
|
106
|
+
visibility: hidden;
|
|
107
|
+
transform: translateY(8px) scale(0.96);
|
|
108
|
+
transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease;
|
|
109
|
+
font-family: -apple-system, 'Segoe UI', system-ui, sans-serif;
|
|
110
|
+
font-size: 13px;
|
|
111
|
+
color: var(--vscode-foreground, #ccc);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.agy-rtl-panel.visible {
|
|
115
|
+
opacity: 1;
|
|
116
|
+
visibility: visible;
|
|
117
|
+
transform: translateY(0) scale(1);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* āā Panel Header āā */
|
|
121
|
+
|
|
122
|
+
.agy-rtl-panel-header {
|
|
123
|
+
margin-bottom: 14px;
|
|
124
|
+
padding-bottom: 10px;
|
|
125
|
+
border-bottom: 1px solid var(--vscode-editorWidget-border, #3a3a3a);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.agy-rtl-panel-title {
|
|
129
|
+
font-size: 14px;
|
|
130
|
+
font-weight: 600;
|
|
131
|
+
color: var(--vscode-foreground, #e0e0e0);
|
|
132
|
+
letter-spacing: -0.01em;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* āā Panel Row āā */
|
|
136
|
+
|
|
137
|
+
.agy-rtl-panel-row {
|
|
138
|
+
display: flex;
|
|
139
|
+
align-items: center;
|
|
140
|
+
justify-content: space-between;
|
|
141
|
+
padding: 6px 0;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.agy-rtl-panel-label {
|
|
145
|
+
font-size: 13px;
|
|
146
|
+
color: var(--vscode-foreground, #ccc);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/* āā Separator āā */
|
|
150
|
+
|
|
151
|
+
.agy-rtl-panel-sep {
|
|
152
|
+
height: 1px;
|
|
153
|
+
background: var(--vscode-editorWidget-border, #3a3a3a);
|
|
154
|
+
margin: 8px 0;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* āā Toggle Switch āā */
|
|
158
|
+
|
|
159
|
+
.agy-rtl-switch {
|
|
160
|
+
position: relative;
|
|
161
|
+
display: inline-block;
|
|
162
|
+
width: 40px;
|
|
163
|
+
height: 22px;
|
|
164
|
+
cursor: pointer;
|
|
165
|
+
flex-shrink: 0;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.agy-rtl-switch input {
|
|
169
|
+
opacity: 0;
|
|
170
|
+
width: 0;
|
|
171
|
+
height: 0;
|
|
172
|
+
position: absolute;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.agy-rtl-slider {
|
|
176
|
+
position: absolute;
|
|
177
|
+
top: 0;
|
|
178
|
+
left: 0;
|
|
179
|
+
right: 0;
|
|
180
|
+
bottom: 0;
|
|
181
|
+
background: #555;
|
|
182
|
+
border-radius: 22px;
|
|
183
|
+
transition: background 0.25s ease, box-shadow 0.25s ease;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.agy-rtl-slider::before {
|
|
187
|
+
content: '';
|
|
188
|
+
position: absolute;
|
|
189
|
+
width: 16px;
|
|
190
|
+
height: 16px;
|
|
191
|
+
left: 3px;
|
|
192
|
+
bottom: 3px;
|
|
193
|
+
background: #fff;
|
|
194
|
+
border-radius: 50%;
|
|
195
|
+
transition: transform 0.25s ease;
|
|
196
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.3);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.agy-rtl-switch input:checked + .agy-rtl-slider {
|
|
200
|
+
background: #4b9cf5;
|
|
201
|
+
box-shadow: 0 0 8px rgba(75, 156, 245, 0.3);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.agy-rtl-switch input:checked + .agy-rtl-slider::before {
|
|
205
|
+
transform: translateX(18px);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.agy-rtl-switch input:focus-visible + .agy-rtl-slider {
|
|
209
|
+
outline: 2px solid var(--vscode-focusBorder, #007fd4);
|
|
210
|
+
outline-offset: 2px;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/* āā GitHub Link āā */
|
|
214
|
+
|
|
215
|
+
.agy-rtl-panel-gh {
|
|
216
|
+
justify-content: center;
|
|
217
|
+
padding-top: 4px;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.agy-rtl-gh-link {
|
|
221
|
+
display: inline-flex;
|
|
222
|
+
align-items: center;
|
|
223
|
+
gap: 6px;
|
|
224
|
+
color: var(--vscode-textLink-foreground, #9cdcfe);
|
|
225
|
+
text-decoration: none;
|
|
226
|
+
font-size: 12px;
|
|
227
|
+
opacity: 0.8;
|
|
228
|
+
transition: opacity 0.2s ease;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.agy-rtl-gh-link:hover {
|
|
232
|
+
opacity: 1;
|
|
233
|
+
text-decoration: underline;
|
|
234
|
+
}
|
package/src/patcher.js
CHANGED
|
@@ -13,7 +13,7 @@ const ENGINE_FILENAME = 'agy-rtl-engine.js';
|
|
|
13
13
|
const STYLES_FILENAME = 'agy-rtl-styles.css';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Patch an unpacked Antigravity
|
|
16
|
+
* Patch an unpacked Antigravity installation.
|
|
17
17
|
* Copies payload files and modifies workbench.html.
|
|
18
18
|
*/
|
|
19
19
|
async function patchUnpacked(installation, spinner) {
|
|
@@ -166,14 +166,14 @@ async function patchAsar(installation, spinner) {
|
|
|
166
166
|
* Main patch function.
|
|
167
167
|
*/
|
|
168
168
|
async function patch(customPath) {
|
|
169
|
-
const spinner = ora('Searching for Antigravity
|
|
169
|
+
const spinner = ora('Searching for Antigravity...').start();
|
|
170
170
|
|
|
171
171
|
const installations = findInstallations(customPath);
|
|
172
172
|
|
|
173
173
|
if (installations.length === 0) {
|
|
174
|
-
spinner.fail('Antigravity
|
|
174
|
+
spinner.fail('Antigravity installation not found.');
|
|
175
175
|
console.error(chalk.yellow('\nTry specifying the path manually:'));
|
|
176
|
-
console.error(chalk.cyan(' agy-rtl patch --path /path/to/Antigravity
|
|
176
|
+
console.error(chalk.cyan(' agy-rtl patch --path /path/to/Antigravity\n'));
|
|
177
177
|
throw new Error('Installation not found.');
|
|
178
178
|
}
|
|
179
179
|
|
|
@@ -192,8 +192,8 @@ async function patch(customPath) {
|
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
console.log(chalk.green.bold('\n⨠Antigravity
|
|
196
|
-
console.log(chalk.cyan(' Please restart Antigravity
|
|
195
|
+
console.log(chalk.green.bold('\n⨠Antigravity successfully patched with RTL support!'));
|
|
196
|
+
console.log(chalk.cyan(' Please restart Antigravity for changes to take effect.\n'));
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
/**
|
|
@@ -242,11 +242,11 @@ async function restoreAsar(installation, spinner) {
|
|
|
242
242
|
* Main restore function.
|
|
243
243
|
*/
|
|
244
244
|
async function restore(customPath) {
|
|
245
|
-
const spinner = ora('Searching for Antigravity
|
|
245
|
+
const spinner = ora('Searching for Antigravity...').start();
|
|
246
246
|
const installations = findInstallations(customPath);
|
|
247
247
|
|
|
248
248
|
if (installations.length === 0) {
|
|
249
|
-
spinner.fail('Antigravity
|
|
249
|
+
spinner.fail('Antigravity installation not found.');
|
|
250
250
|
throw new Error('Installation not found.');
|
|
251
251
|
}
|
|
252
252
|
|
|
@@ -264,19 +264,19 @@ async function restore(customPath) {
|
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
-
console.log(chalk.green.bold('\n⨠Antigravity
|
|
268
|
-
console.log(chalk.cyan(' Please restart Antigravity
|
|
267
|
+
console.log(chalk.green.bold('\n⨠Antigravity restored to original state!'));
|
|
268
|
+
console.log(chalk.cyan(' Please restart Antigravity for changes to take effect.\n'));
|
|
269
269
|
}
|
|
270
270
|
|
|
271
271
|
/**
|
|
272
272
|
* Check patch status.
|
|
273
273
|
*/
|
|
274
274
|
async function status(customPath) {
|
|
275
|
-
const spinner = ora('Searching for Antigravity
|
|
275
|
+
const spinner = ora('Searching for Antigravity...').start();
|
|
276
276
|
const installations = findInstallations(customPath);
|
|
277
277
|
|
|
278
278
|
if (installations.length === 0) {
|
|
279
|
-
spinner.fail('Antigravity
|
|
279
|
+
spinner.fail('Antigravity installation not found.');
|
|
280
280
|
return;
|
|
281
281
|
}
|
|
282
282
|
|
package/src/paths.js
CHANGED
|
@@ -3,7 +3,7 @@ const path = require('path');
|
|
|
3
3
|
const os = require('os');
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Known installation paths for Antigravity
|
|
6
|
+
* Known installation paths for Antigravity across all platforms.
|
|
7
7
|
* Both the IDE (unpacked) and the standalone app (asar) are supported.
|
|
8
8
|
*/
|
|
9
9
|
function getSearchPaths() {
|
|
@@ -11,37 +11,52 @@ function getSearchPaths() {
|
|
|
11
11
|
const platform = os.platform();
|
|
12
12
|
|
|
13
13
|
const common = [
|
|
14
|
-
//
|
|
15
|
-
path.join(home, 'Downloads', 'Antigravity-IDE'),
|
|
16
|
-
path.join(home, 'Downloads', 'Antigravity-x64'),
|
|
14
|
+
// Antigravity (primary target)
|
|
17
15
|
path.join(home, 'Downloads', 'Antigravity'),
|
|
18
|
-
|
|
19
|
-
path.join(home, 'Desktop', 'Antigravity
|
|
16
|
+
path.join(home, 'Downloads', 'Antigravity-x64'),
|
|
17
|
+
path.join(home, 'Desktop', 'Antigravity'),
|
|
20
18
|
path.join(home, 'Desktop', 'Antigravity-x64'),
|
|
19
|
+
// Antigravity IDE (backward compatibility)
|
|
20
|
+
path.join(home, 'Downloads', 'Antigravity-IDE'),
|
|
21
|
+
path.join(home, 'Desktop', 'Antigravity-IDE'),
|
|
21
22
|
];
|
|
22
23
|
|
|
23
24
|
const platformPaths = {
|
|
24
25
|
linux: [
|
|
25
|
-
|
|
26
|
+
// Antigravity (primary)
|
|
27
|
+
'/opt/antigravity',
|
|
28
|
+
'/opt/Antigravity',
|
|
29
|
+
'/usr/lib/antigravity',
|
|
30
|
+
'/usr/share/antigravity',
|
|
31
|
+
path.join(home, '.local', 'share', 'antigravity'),
|
|
32
|
+
path.join(home, '.local', 'lib', 'antigravity'),
|
|
33
|
+
// Antigravity IDE (fallback)
|
|
26
34
|
'/opt/antigravity-ide',
|
|
27
35
|
'/opt/Antigravity-IDE',
|
|
28
|
-
'/opt/antigravity',
|
|
29
36
|
'/usr/lib/antigravity-ide',
|
|
30
37
|
'/usr/share/antigravity-ide',
|
|
31
38
|
path.join(home, '.local', 'share', 'antigravity-ide'),
|
|
32
39
|
path.join(home, '.local', 'lib', 'antigravity-ide'),
|
|
40
|
+
...common,
|
|
33
41
|
],
|
|
34
42
|
darwin: [
|
|
43
|
+
// Antigravity (primary)
|
|
44
|
+
'/Applications/Antigravity.app/Contents',
|
|
45
|
+
path.join(home, 'Applications', 'Antigravity.app', 'Contents'),
|
|
46
|
+
// Antigravity IDE (fallback)
|
|
35
47
|
'/Applications/Antigravity IDE.app/Contents',
|
|
36
48
|
path.join(home, 'Applications', 'Antigravity IDE.app', 'Contents'),
|
|
37
|
-
'/Applications/Antigravity.app/Contents',
|
|
38
49
|
...common,
|
|
39
50
|
],
|
|
40
51
|
win32: [
|
|
52
|
+
// Antigravity (primary)
|
|
53
|
+
path.join(process.env.LOCALAPPDATA || '', 'Programs', 'antigravity'),
|
|
54
|
+
path.join(process.env.LOCALAPPDATA || '', 'Programs', 'Antigravity'),
|
|
55
|
+
path.join(process.env.PROGRAMFILES || '', 'Antigravity'),
|
|
56
|
+
// Antigravity IDE (fallback)
|
|
41
57
|
path.join(process.env.LOCALAPPDATA || '', 'Programs', 'antigravity-ide'),
|
|
42
58
|
path.join(process.env.LOCALAPPDATA || '', 'Programs', 'Antigravity IDE'),
|
|
43
59
|
path.join(process.env.PROGRAMFILES || '', 'Antigravity IDE'),
|
|
44
|
-
path.join(process.env.LOCALAPPDATA || '', 'Programs', 'antigravity'),
|
|
45
60
|
...common,
|
|
46
61
|
],
|
|
47
62
|
};
|
|
@@ -85,7 +100,7 @@ function detectInstallation(basePath) {
|
|
|
85
100
|
}
|
|
86
101
|
|
|
87
102
|
/**
|
|
88
|
-
* Find all Antigravity
|
|
103
|
+
* Find all Antigravity installations on the system.
|
|
89
104
|
*/
|
|
90
105
|
function findInstallations(customPath) {
|
|
91
106
|
const results = [];
|