abstractassistant 0.2.0__py3-none-any.whl → 0.2.6__py3-none-any.whl
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.
- abstractassistant/core/llm_manager.py +15 -11
- abstractassistant/create_app_bundle.py +48 -0
- abstractassistant/ui/history_dialog.py +142 -42
- abstractassistant/ui/qt_bubble.py +231 -58
- abstractassistant/ui/toast_window.py +8 -8
- abstractassistant/ui/ui_styles.py +2 -2
- abstractassistant/utils/markdown_renderer.py +1 -1
- {abstractassistant-0.2.0.dist-info → abstractassistant-0.2.6.dist-info}/METADATA +28 -5
- {abstractassistant-0.2.0.dist-info → abstractassistant-0.2.6.dist-info}/RECORD +14 -12
- abstractassistant-0.2.6.dist-info/entry_points.txt +3 -0
- {abstractassistant-0.2.0.dist-info → abstractassistant-0.2.6.dist-info}/top_level.txt +1 -0
- setup_macos_app.py +269 -0
- abstractassistant-0.2.0.dist-info/entry_points.txt +0 -2
- {abstractassistant-0.2.0.dist-info → abstractassistant-0.2.6.dist-info}/WHEEL +0 -0
- {abstractassistant-0.2.0.dist-info → abstractassistant-0.2.6.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: abstractassistant
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: A sleek (macOS) system tray application providing instant access to LLMs
|
|
5
5
|
Author-email: Laurent-Philippe Albou <contact@abstractcore.ai>
|
|
6
|
-
License: MIT
|
|
6
|
+
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/lpalbou/abstractassistant
|
|
8
8
|
Project-URL: Repository, https://github.com/lpalbou/abstractassistant
|
|
9
9
|
Project-URL: Issues, https://github.com/lpalbou/abstractassistant/issues
|
|
10
10
|
Keywords: ai,llm,macos,system-tray,assistant
|
|
11
11
|
Classifier: Development Status :: 4 - Beta
|
|
12
12
|
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
14
13
|
Classifier: Operating System :: MacOS
|
|
15
14
|
Classifier: Programming Language :: Python :: 3
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.9
|
|
@@ -22,12 +21,13 @@ Classifier: Topic :: Desktop Environment
|
|
|
22
21
|
Requires-Python: >=3.9
|
|
23
22
|
Description-Content-Type: text/markdown
|
|
24
23
|
License-File: LICENSE
|
|
25
|
-
Requires-Dist: abstractcore[all]>=2.4.
|
|
24
|
+
Requires-Dist: abstractcore[all]>=2.4.5
|
|
26
25
|
Requires-Dist: pystray>=0.19.4
|
|
27
26
|
Requires-Dist: Pillow>=10.0.0
|
|
28
27
|
Requires-Dist: PyQt5>=5.15.0
|
|
29
28
|
Requires-Dist: markdown>=3.5.0
|
|
30
29
|
Requires-Dist: pygments>=2.16.0
|
|
30
|
+
Requires-Dist: pymdown-extensions>=10.0
|
|
31
31
|
Requires-Dist: abstractvoice>=0.5.0
|
|
32
32
|
Requires-Dist: pyperclip>=1.8.2
|
|
33
33
|
Requires-Dist: plyer>=2.1.0
|
|
@@ -66,17 +66,40 @@ A sleek macOS system tray application providing instant access to Large Language
|
|
|
66
66
|
## 🚀 Quick Start
|
|
67
67
|
|
|
68
68
|
### 1. Installation
|
|
69
|
+
|
|
70
|
+
#### 🍎 macOS Users (Recommended)
|
|
71
|
+
```bash
|
|
72
|
+
# Enhanced installation with Dock integration
|
|
73
|
+
python3 install.py
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This will:
|
|
77
|
+
- Install AbstractAssistant from PyPI
|
|
78
|
+
- Create a macOS app bundle in `/Applications`
|
|
79
|
+
- Add AbstractAssistant to your Dock for easy access
|
|
80
|
+
|
|
81
|
+
#### 🔧 Standard Installation
|
|
69
82
|
```bash
|
|
70
|
-
# Install from PyPI
|
|
83
|
+
# Install from PyPI
|
|
71
84
|
pip install abstractassistant
|
|
72
85
|
```
|
|
73
86
|
|
|
74
87
|
For detailed installation instructions including prerequisites and voice setup, see **[📖 Installation Guide](docs/installation.md)**.
|
|
75
88
|
|
|
76
89
|
### 2. First Launch
|
|
90
|
+
|
|
91
|
+
#### 🍎 macOS App Bundle Users
|
|
92
|
+
- **Dock**: Click the AbstractAssistant icon in your Dock
|
|
93
|
+
- **Spotlight**: Search for "AbstractAssistant" and press Enter
|
|
94
|
+
- **Finder**: Open `/Applications/AbstractAssistant.app`
|
|
95
|
+
|
|
96
|
+
#### 🔧 Terminal Users
|
|
77
97
|
```bash
|
|
78
98
|
# Launch the assistant
|
|
79
99
|
assistant
|
|
100
|
+
|
|
101
|
+
# Or create macOS app bundle after installation
|
|
102
|
+
create-app-bundle
|
|
80
103
|
```
|
|
81
104
|
|
|
82
105
|
### 3. Start Using
|
|
@@ -1,26 +1,28 @@
|
|
|
1
|
+
setup_macos_app.py,sha256=PP-X7UVfv8VmwaOtmNao0Bn3P5oXRAgfs13TXMpNhA8,8806
|
|
1
2
|
abstractassistant/__init__.py,sha256=homfqMDh6sX2nBROtk6-y72jnrStPph8gEOeT0OjKyU,35
|
|
2
3
|
abstractassistant/app.py,sha256=-Nkgj1IruGhiuyMt7-EQPBwxXoeIykaO1FYKlS520zA,34032
|
|
3
4
|
abstractassistant/cli.py,sha256=SQPxQCLjX-LOlhSEvG302D0AOyxlxo5QM2imxr9wxmc,4385
|
|
4
5
|
abstractassistant/config.py,sha256=KodfPYTpHtavJyne-h-B-r3kbEt1uusSY8GknGLtDL8,5809
|
|
6
|
+
abstractassistant/create_app_bundle.py,sha256=PrOKIaYMW-v3gAEPCxaS2FUkhCfVd6PRU99DxYEEcXs,1471
|
|
5
7
|
abstractassistant/web_server.py,sha256=_pqMzy13qfim9BMBqQJQifWyX7UQXFD_sZeiu4ZBt40,12816
|
|
6
8
|
abstractassistant/core/__init__.py,sha256=TETStgToTe7QSsCZgRHDk2oSErlLJoeGN0sFg4Yx2_c,15
|
|
7
|
-
abstractassistant/core/llm_manager.py,sha256=
|
|
9
|
+
abstractassistant/core/llm_manager.py,sha256=yIvFj0pSLeC22PsaD0a3I4PjylO5Qvju8P_1e9iyXAM,11376
|
|
8
10
|
abstractassistant/core/tts_manager.py,sha256=vE5SOh16CmeWp_ml_tehmSZxj503KEjz0uCQPXpWOpQ,7819
|
|
9
11
|
abstractassistant/ui/__init__.py,sha256=aRNE2pS50nFAX6y--rSGMNYwhz905g14gRd6g4BolYU,13
|
|
10
12
|
abstractassistant/ui/chat_bubble.py,sha256=TE6zPtQ46I9grKGAb744wHqk4yO6-und3iif8_33XGk,11357
|
|
11
|
-
abstractassistant/ui/history_dialog.py,sha256=
|
|
13
|
+
abstractassistant/ui/history_dialog.py,sha256=jLi8JV6z_yN6yXBsRAF6cPfyPjwsUB-FYlBaInQRF3U,18523
|
|
12
14
|
abstractassistant/ui/provider_manager.py,sha256=9IM-BxIs6lUlk6cDCBi7oZFMXmn4CFMlxh0s-_vhzXY,8403
|
|
13
|
-
abstractassistant/ui/qt_bubble.py,sha256=
|
|
15
|
+
abstractassistant/ui/qt_bubble.py,sha256=X9cgvV-s1V_kFQNCB9lr9ODc-raeFoYTIFYepz_uCRc,89142
|
|
14
16
|
abstractassistant/ui/toast_manager.py,sha256=1aU4DPo-J45bC61gTEctHq98ZrHIFxRfZa_9Q8KF588,13721
|
|
15
|
-
abstractassistant/ui/toast_window.py,sha256=
|
|
17
|
+
abstractassistant/ui/toast_window.py,sha256=EYGRQOzQeR9MYrfdzkxN6FH-y7CaW8Noy5kw3CpQlmw,21609
|
|
16
18
|
abstractassistant/ui/tts_state_manager.py,sha256=UF_zrfl9wf0hNHBGxevcoKxW5Dh7zXibUSVoSSjGP4o,10565
|
|
17
|
-
abstractassistant/ui/ui_styles.py,sha256=
|
|
19
|
+
abstractassistant/ui/ui_styles.py,sha256=VoGlrZI3YJzDKPv9LWz39W3XcFI4N952rkzXb8Musfw,13150
|
|
18
20
|
abstractassistant/utils/__init__.py,sha256=7Q3BxyXETkt3tm5trhuLTyL8PoECOK0QiK-0KUVAR2Q,16
|
|
19
21
|
abstractassistant/utils/icon_generator.py,sha256=MH3giercjE6Dh100EZ_8kw5WC0PVwd5F4inKfRDLp2w,10455
|
|
20
|
-
abstractassistant/utils/markdown_renderer.py,sha256=
|
|
21
|
-
abstractassistant-0.2.
|
|
22
|
-
abstractassistant-0.2.
|
|
23
|
-
abstractassistant-0.2.
|
|
24
|
-
abstractassistant-0.2.
|
|
25
|
-
abstractassistant-0.2.
|
|
26
|
-
abstractassistant-0.2.
|
|
22
|
+
abstractassistant/utils/markdown_renderer.py,sha256=sTn045glqxh5QU3LIuYp7zQpBIuwf5e3cWZzDz5i0Yw,12620
|
|
23
|
+
abstractassistant-0.2.6.dist-info/licenses/LICENSE,sha256=QUjFNAE-0yOkW9-Rle2axkpkt9H7xiZ2VbN-VeONhxc,1106
|
|
24
|
+
abstractassistant-0.2.6.dist-info/METADATA,sha256=7OmP5oqZ9ZPzCyTWGbRH-xCBmpr92q-jKnofEmC4u_8,11156
|
|
25
|
+
abstractassistant-0.2.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
26
|
+
abstractassistant-0.2.6.dist-info/entry_points.txt,sha256=MIzeCh0XG6MbhIzBHtkdEjmjxYBsQrGFevq8Y1L8Jkc,118
|
|
27
|
+
abstractassistant-0.2.6.dist-info/top_level.txt,sha256=oEcSXZAqbflTfZRfF4dogUq6TC1Nqyplq4JgC0CZnLI,34
|
|
28
|
+
abstractassistant-0.2.6.dist-info/RECORD,,
|
setup_macos_app.py
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
macOS App Bundle Generator for AbstractAssistant.
|
|
4
|
+
|
|
5
|
+
This module creates a macOS .app bundle during installation,
|
|
6
|
+
allowing users to launch AbstractAssistant from the Dock.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
|
+
import shutil
|
|
12
|
+
import subprocess
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Optional
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
from PIL import Image
|
|
18
|
+
PIL_AVAILABLE = True
|
|
19
|
+
except ImportError:
|
|
20
|
+
PIL_AVAILABLE = False
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class MacOSAppBundleGenerator:
|
|
24
|
+
"""Generates macOS app bundles for AbstractAssistant."""
|
|
25
|
+
|
|
26
|
+
def __init__(self, package_dir: Path):
|
|
27
|
+
"""Initialize the app bundle generator.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
package_dir: Path to the abstractassistant package directory
|
|
31
|
+
"""
|
|
32
|
+
self.package_dir = package_dir
|
|
33
|
+
self.app_name = "AbstractAssistant"
|
|
34
|
+
self.app_bundle_path = Path("/Applications") / f"{self.app_name}.app"
|
|
35
|
+
|
|
36
|
+
def is_macos(self) -> bool:
|
|
37
|
+
"""Check if running on macOS."""
|
|
38
|
+
return sys.platform == "darwin"
|
|
39
|
+
|
|
40
|
+
def has_permissions(self) -> bool:
|
|
41
|
+
"""Check if we have permissions to write to /Applications."""
|
|
42
|
+
try:
|
|
43
|
+
test_file = Path("/Applications") / ".test_write_permission"
|
|
44
|
+
test_file.touch()
|
|
45
|
+
test_file.unlink()
|
|
46
|
+
return True
|
|
47
|
+
except (PermissionError, OSError):
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
def create_app_bundle_structure(self) -> bool:
|
|
51
|
+
"""Create the basic app bundle directory structure."""
|
|
52
|
+
try:
|
|
53
|
+
# Create main directories
|
|
54
|
+
contents_dir = self.app_bundle_path / "Contents"
|
|
55
|
+
macos_dir = contents_dir / "MacOS"
|
|
56
|
+
resources_dir = contents_dir / "Resources"
|
|
57
|
+
|
|
58
|
+
for directory in [contents_dir, macos_dir, resources_dir]:
|
|
59
|
+
directory.mkdir(parents=True, exist_ok=True)
|
|
60
|
+
|
|
61
|
+
return True
|
|
62
|
+
except Exception as e:
|
|
63
|
+
print(f"Error creating app bundle structure: {e}")
|
|
64
|
+
return False
|
|
65
|
+
|
|
66
|
+
def generate_app_icon(self) -> bool:
|
|
67
|
+
"""Generate the app icon using the existing icon generator."""
|
|
68
|
+
try:
|
|
69
|
+
# Import the icon generator
|
|
70
|
+
sys.path.insert(0, str(self.package_dir))
|
|
71
|
+
from abstractassistant.utils.icon_generator import IconGenerator
|
|
72
|
+
|
|
73
|
+
# Generate high-resolution icon
|
|
74
|
+
generator = IconGenerator(size=512)
|
|
75
|
+
icon = generator.create_app_icon('blue', animated=False)
|
|
76
|
+
|
|
77
|
+
# Save as PNG
|
|
78
|
+
icon_path = self.app_bundle_path / "Contents" / "Resources" / "icon.png"
|
|
79
|
+
icon.save(str(icon_path))
|
|
80
|
+
|
|
81
|
+
# Create ICNS file
|
|
82
|
+
return self._create_icns_file(icon_path)
|
|
83
|
+
|
|
84
|
+
except Exception as e:
|
|
85
|
+
print(f"Error generating app icon: {e}")
|
|
86
|
+
return False
|
|
87
|
+
|
|
88
|
+
def _create_icns_file(self, png_path: Path) -> bool:
|
|
89
|
+
"""Create ICNS file from PNG using macOS iconutil."""
|
|
90
|
+
try:
|
|
91
|
+
# Create iconset directory
|
|
92
|
+
iconset_dir = png_path.parent / "temp_icons.iconset"
|
|
93
|
+
iconset_dir.mkdir(exist_ok=True)
|
|
94
|
+
|
|
95
|
+
# Load the PNG and create different sizes
|
|
96
|
+
icon = Image.open(png_path)
|
|
97
|
+
sizes = [
|
|
98
|
+
(16, 'icon_16x16.png'),
|
|
99
|
+
(32, 'icon_16x16@2x.png'),
|
|
100
|
+
(32, 'icon_32x32.png'),
|
|
101
|
+
(64, 'icon_32x32@2x.png'),
|
|
102
|
+
(128, 'icon_128x128.png'),
|
|
103
|
+
(256, 'icon_128x128@2x.png'),
|
|
104
|
+
(256, 'icon_256x256.png'),
|
|
105
|
+
(512, 'icon_256x256@2x.png'),
|
|
106
|
+
(512, 'icon_512x512.png'),
|
|
107
|
+
(1024, 'icon_512x512@2x.png')
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
for size, filename in sizes:
|
|
111
|
+
resized = icon.resize((size, size), Image.Resampling.LANCZOS)
|
|
112
|
+
resized.save(iconset_dir / filename)
|
|
113
|
+
|
|
114
|
+
# Convert to ICNS
|
|
115
|
+
icns_path = png_path.parent / "icon.icns"
|
|
116
|
+
result = subprocess.run([
|
|
117
|
+
'iconutil', '-c', 'icns', str(iconset_dir),
|
|
118
|
+
'-o', str(icns_path)
|
|
119
|
+
], capture_output=True, text=True)
|
|
120
|
+
|
|
121
|
+
# Clean up
|
|
122
|
+
shutil.rmtree(iconset_dir)
|
|
123
|
+
|
|
124
|
+
return result.returncode == 0
|
|
125
|
+
|
|
126
|
+
except Exception as e:
|
|
127
|
+
print(f"Error creating ICNS file: {e}")
|
|
128
|
+
return False
|
|
129
|
+
|
|
130
|
+
def create_info_plist(self) -> bool:
|
|
131
|
+
"""Create the Info.plist file."""
|
|
132
|
+
try:
|
|
133
|
+
plist_content = '''<?xml version="1.0" encoding="UTF-8"?>
|
|
134
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
135
|
+
<plist version="1.0">
|
|
136
|
+
<dict>
|
|
137
|
+
<key>CFBundleExecutable</key>
|
|
138
|
+
<string>AbstractAssistant</string>
|
|
139
|
+
<key>CFBundleIdentifier</key>
|
|
140
|
+
<string>ai.abstractcore.abstractassistant</string>
|
|
141
|
+
<key>CFBundleName</key>
|
|
142
|
+
<string>AbstractAssistant</string>
|
|
143
|
+
<key>CFBundleDisplayName</key>
|
|
144
|
+
<string>AbstractAssistant</string>
|
|
145
|
+
<key>CFBundleVersion</key>
|
|
146
|
+
<string>0.2.5</string>
|
|
147
|
+
<key>CFBundleShortVersionString</key>
|
|
148
|
+
<string>0.2.5</string>
|
|
149
|
+
<key>CFBundlePackageType</key>
|
|
150
|
+
<string>APPL</string>
|
|
151
|
+
<key>CFBundleSignature</key>
|
|
152
|
+
<string>????</string>
|
|
153
|
+
<key>CFBundleIconFile</key>
|
|
154
|
+
<string>icon.icns</string>
|
|
155
|
+
<key>LSMinimumSystemVersion</key>
|
|
156
|
+
<string>10.15</string>
|
|
157
|
+
<key>NSHighResolutionCapable</key>
|
|
158
|
+
<true/>
|
|
159
|
+
<key>NSRequiresAquaSystemAppearance</key>
|
|
160
|
+
<false/>
|
|
161
|
+
<key>LSUIElement</key>
|
|
162
|
+
<true/>
|
|
163
|
+
<key>NSAppleScriptEnabled</key>
|
|
164
|
+
<false/>
|
|
165
|
+
<key>CFBundleDocumentTypes</key>
|
|
166
|
+
<array/>
|
|
167
|
+
<key>NSPrincipalClass</key>
|
|
168
|
+
<string>NSApplication</string>
|
|
169
|
+
</dict>
|
|
170
|
+
</plist>'''
|
|
171
|
+
|
|
172
|
+
plist_path = self.app_bundle_path / "Contents" / "Info.plist"
|
|
173
|
+
plist_path.write_text(plist_content)
|
|
174
|
+
return True
|
|
175
|
+
|
|
176
|
+
except Exception as e:
|
|
177
|
+
print(f"Error creating Info.plist: {e}")
|
|
178
|
+
return False
|
|
179
|
+
|
|
180
|
+
def create_launch_script(self) -> bool:
|
|
181
|
+
"""Create the executable launch script."""
|
|
182
|
+
try:
|
|
183
|
+
script_content = '''#!/bin/bash
|
|
184
|
+
|
|
185
|
+
# AbstractAssistant macOS App Launcher
|
|
186
|
+
# This script launches the AbstractAssistant application
|
|
187
|
+
|
|
188
|
+
# Find the Python executable and package
|
|
189
|
+
PYTHON_EXEC="$(which python3)"
|
|
190
|
+
if [ -z "$PYTHON_EXEC" ]; then
|
|
191
|
+
PYTHON_EXEC="$(which python)"
|
|
192
|
+
fi
|
|
193
|
+
|
|
194
|
+
if [ -z "$PYTHON_EXEC" ]; then
|
|
195
|
+
echo "Error: Python not found in PATH"
|
|
196
|
+
exit 1
|
|
197
|
+
fi
|
|
198
|
+
|
|
199
|
+
# Launch the assistant
|
|
200
|
+
exec "$PYTHON_EXEC" -m abstractassistant.cli "$@"'''
|
|
201
|
+
|
|
202
|
+
script_path = self.app_bundle_path / "Contents" / "MacOS" / "AbstractAssistant"
|
|
203
|
+
script_path.write_text(script_content)
|
|
204
|
+
|
|
205
|
+
# Make executable
|
|
206
|
+
os.chmod(script_path, 0o755)
|
|
207
|
+
return True
|
|
208
|
+
|
|
209
|
+
except Exception as e:
|
|
210
|
+
print(f"Error creating launch script: {e}")
|
|
211
|
+
return False
|
|
212
|
+
|
|
213
|
+
def generate_app_bundle(self) -> bool:
|
|
214
|
+
"""Generate the complete macOS app bundle."""
|
|
215
|
+
if not self.is_macos():
|
|
216
|
+
print("macOS app bundle generation is only available on macOS")
|
|
217
|
+
return False
|
|
218
|
+
|
|
219
|
+
if not self.has_permissions():
|
|
220
|
+
print("Insufficient permissions to create app bundle in /Applications")
|
|
221
|
+
print("Please run with sudo or manually copy the app bundle")
|
|
222
|
+
return False
|
|
223
|
+
|
|
224
|
+
print("Creating macOS app bundle...")
|
|
225
|
+
|
|
226
|
+
# Remove existing bundle if it exists
|
|
227
|
+
if self.app_bundle_path.exists():
|
|
228
|
+
shutil.rmtree(self.app_bundle_path)
|
|
229
|
+
|
|
230
|
+
# Create bundle structure
|
|
231
|
+
if not self.create_app_bundle_structure():
|
|
232
|
+
return False
|
|
233
|
+
|
|
234
|
+
# Generate icon
|
|
235
|
+
if not self.generate_app_icon():
|
|
236
|
+
return False
|
|
237
|
+
|
|
238
|
+
# Create Info.plist
|
|
239
|
+
if not self.create_info_plist():
|
|
240
|
+
return False
|
|
241
|
+
|
|
242
|
+
# Create launch script
|
|
243
|
+
if not self.create_launch_script():
|
|
244
|
+
return False
|
|
245
|
+
|
|
246
|
+
print(f"✅ macOS app bundle created successfully!")
|
|
247
|
+
print(f" Location: {self.app_bundle_path}")
|
|
248
|
+
print(f" You can now launch AbstractAssistant from the Dock!")
|
|
249
|
+
|
|
250
|
+
return True
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def create_macos_app_bundle():
|
|
254
|
+
"""Main function to create macOS app bundle during installation."""
|
|
255
|
+
try:
|
|
256
|
+
# Find the package directory
|
|
257
|
+
package_dir = Path(__file__).parent
|
|
258
|
+
|
|
259
|
+
generator = MacOSAppBundleGenerator(package_dir)
|
|
260
|
+
return generator.generate_app_bundle()
|
|
261
|
+
|
|
262
|
+
except Exception as e:
|
|
263
|
+
print(f"Error creating macOS app bundle: {e}")
|
|
264
|
+
return False
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
if __name__ == "__main__":
|
|
268
|
+
success = create_macos_app_bundle()
|
|
269
|
+
sys.exit(0 if success else 1)
|
|
File without changes
|
|
File without changes
|