Skip to content

Commit 9debc65

Browse files
committed
fix: remove erroneous 'return True' in _show_version_details that caused early exit
1 parent aaebd51 commit 9debc65

5 files changed

Lines changed: 376 additions & 20 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
55

66
[project]
77
name = "omnipkg"
8-
version = "2.0.8"
8+
version = "2.0.8.1"
99
authors = [
1010
{ name = "1minds3t", email = "1minds3t@proton.me" },
1111
]

src/omnipkg/apis/local_bridge.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
import sys
2+
import os
3+
import signal
4+
import logging
5+
import threading
6+
import webbrowser
7+
import subprocess
8+
import shlex
9+
import time
10+
from pathlib import Path
11+
from flask import Flask, request, jsonify, make_response
12+
13+
# --- Imports & Configuration ---
14+
try:
15+
from flask_cors import CORS
16+
HAS_WEB_DEPS = True
17+
except ImportError:
18+
HAS_WEB_DEPS = False
19+
20+
try:
21+
from omnipkg.utils.flask_port_finder import find_free_port
22+
except ImportError:
23+
def find_free_port(start_port=5000, **kwargs): return start_port
24+
25+
ALLOWED_ORIGIN = "https://omnipkg.1minds3t.workers.dev"
26+
PID_FILE = Path.home() / ".omnipkg" / "web_bridge.pid"
27+
28+
# --- FLASK APP LOGIC (Same as before) ---
29+
30+
def build_cors_preflight_response():
31+
response = make_response()
32+
response.headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN)
33+
response.headers.add("Access-Control-Allow-Headers", "Content-Type, Private-Network-Access-Request")
34+
response.headers.add("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
35+
response.headers.add("Access-Control-Allow-Private-Network", "true")
36+
return response
37+
38+
def corsify_actual_response(response):
39+
response.headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN)
40+
response.headers.add("Access-Control-Allow-Private-Network", "true")
41+
return response
42+
43+
def execute_omnipkg_command(cmd_str):
44+
try:
45+
args = shlex.split(cmd_str)
46+
# Security: Allow only specific commands if needed, or leave open for dev
47+
full_command = [sys.executable, "-m", "omnipkg"] + args
48+
49+
# Windows: specific flags to prevent popping up new CMD windows
50+
startupinfo = None
51+
if os.name == 'nt':
52+
startupinfo = subprocess.STARTUPINFO()
53+
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
54+
55+
result = subprocess.run(
56+
full_command,
57+
capture_output=True,
58+
text=True,
59+
timeout=60,
60+
env=os.environ.copy(),
61+
startupinfo=startupinfo
62+
)
63+
if result.returncode == 0:
64+
return result.stdout
65+
return f"Error ({result.returncode}):\n{result.stderr}\n{result.stdout}"
66+
except Exception as e:
67+
return f"System Error: {str(e)}"
68+
69+
def create_app(port):
70+
app = Flask(__name__)
71+
log = logging.getLogger('werkzeug')
72+
log.setLevel(logging.ERROR)
73+
74+
@app.route('/health', methods=['GET', 'OPTIONS'])
75+
def health():
76+
if request.method == "OPTIONS": return build_cors_preflight_response()
77+
return corsify_actual_response(jsonify({"status": "connected", "port": port, "version": "2.0.8"}))
78+
79+
@app.route('/run', methods=['POST', 'OPTIONS'])
80+
def run_command():
81+
if request.method == "OPTIONS": return build_cors_preflight_response()
82+
data = request.json
83+
cmd = data.get('command', '')
84+
print(f"⚡ Web Request: omnipkg {cmd}")
85+
output = execute_omnipkg_command(cmd)
86+
return corsify_actual_response(jsonify({"output": output}))
87+
return app
88+
89+
# --- DAEMON MANAGEMENT LOGIC ---
90+
91+
def save_pid(pid):
92+
PID_FILE.parent.mkdir(parents=True, exist_ok=True)
93+
PID_FILE.write_text(str(pid))
94+
95+
def get_pid():
96+
if PID_FILE.exists():
97+
try:
98+
return int(PID_FILE.read_text().strip())
99+
except:
100+
return None
101+
return None
102+
103+
def start_daemon():
104+
"""Starts this script as a detached background process."""
105+
if get_pid():
106+
print("⚠️ Web Bridge is already running.")
107+
return
108+
109+
# Path to this script
110+
script_path = os.path.abspath(__file__)
111+
112+
# Platform specific flags for detaching
113+
if os.name == 'nt':
114+
# Windows detached process
115+
creationflags = subprocess.DETACHED_PROCESS | subprocess.CREATE_NEW_PROCESS_GROUP
116+
process = subprocess.Popen(
117+
[sys.executable, script_path, "--server-mode"],
118+
creationflags=creationflags,
119+
close_fds=True
120+
)
121+
else:
122+
# Linux/Mac detached process (nohup style)
123+
process = subprocess.Popen(
124+
[sys.executable, script_path, "--server-mode"],
125+
stdout=subprocess.DEVNULL,
126+
stderr=subprocess.DEVNULL,
127+
start_new_session=True,
128+
close_fds=True
129+
)
130+
131+
save_pid(process.pid)
132+
print(f"🚀 OmniPkg Web Bridge started in background (PID: {process.pid})")
133+
134+
# We can't know the port immediately in daemon mode easily without a complex handshake,
135+
# so we assume it finds one shortly.
136+
print(f"🌍 Dashboard: {ALLOWED_ORIGIN}")
137+
webbrowser.open(ALLOWED_ORIGIN)
138+
139+
def stop_daemon():
140+
pid = get_pid()
141+
if not pid:
142+
print("❌ No active Web Bridge found.")
143+
return
144+
145+
try:
146+
os.kill(pid, signal.SIGTERM)
147+
print(f"✅ Stopped Web Bridge (PID: {pid})")
148+
except ProcessLookupError:
149+
print("⚠️ Process not found (already stopped?)")
150+
except Exception as e:
151+
print(f"❌ Error stopping process: {e}")
152+
153+
if PID_FILE.exists():
154+
PID_FILE.unlink()
155+
156+
def run_server_blocking():
157+
"""The actual server logic (what runs inside the daemon)."""
158+
if not HAS_WEB_DEPS:
159+
return # Can't log, we are detached
160+
161+
try:
162+
port = find_free_port(start_port=5000, max_attempts=50, reserve=True)
163+
app = create_app(port)
164+
165+
# Optional: Write port to file if you want the CLI to read it later
166+
167+
app.run(port=port, threaded=True)
168+
except Exception as e:
169+
pass # Logging to file recommended here for debugging daemons
170+
171+
if __name__ == "__main__":
172+
if "--server-mode" in sys.argv:
173+
# This is the background process
174+
run_server_blocking()
175+
elif "--stop" in sys.argv:
176+
stop_daemon()
177+
elif "--daemon" in sys.argv:
178+
start_daemon()
179+
else:
180+
# Foreground mode (for debugging)
181+
print("Running in foreground...")
182+
run_server_blocking()
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
{% set name = "omnipkg" %}
2+
{% set version = "2.0.7" %}
3+
4+
package:
5+
name: {{ name|lower }}
6+
version: {{ version }}
7+
8+
source:
9+
url: https://pypi.org/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz
10+
sha256: f07d3bd32e786e5de143b6e07558b1fe5ee1ab08ac701af3f98b8eb05bd8490b
11+
12+
build:
13+
number: 0
14+
noarch: python
15+
# Noarch doesn't need the complex [unix] vs [win] script logic
16+
script: python -m pip install . --no-deps --no-build-isolation -vv
17+
entry_points:
18+
- omnipkg = omnipkg.cli:main
19+
- 8pkg = omnipkg.cli:main
20+
- 8PKG = omnipkg.cli:main
21+
- OMNIPKG = omnipkg.cli:main
22+
23+
requirements:
24+
host:
25+
- python >=3.10 # Aligned with your platform builds
26+
- pip
27+
- setuptools >=61.0
28+
run:
29+
# --- SYNCED WITH PLATFORM BUILD ---
30+
- python >=3.10
31+
- requests >=2.20
32+
- psutil >=5.9.0
33+
- typer >=0.4.0
34+
- rich >=10.0.0
35+
- filelock >=3.20.1
36+
- packaging >=23.0
37+
- tomli # [py<311]
38+
- authlib >=1.6.5
39+
- aiohttp >=3.13.1
40+
- safety >=3.7.0 # [py<314]
41+
- marshmallow >=4.1.2
42+
- pip-audit >=2.6.0 # [py>=314]
43+
# Note: uv is binary, so noarch might warn about arch-specific deps,
44+
# but the solver handles it.
45+
- uv >=0.9.6 # [not ppc64le]
46+
- urllib3 >=1.26.19
47+
- tqdm >=4.67.1
48+
- typing-extensions >=4.0.0
49+
50+
test:
51+
imports:
52+
- omnipkg
53+
commands:
54+
- omnipkg --version
55+
56+
about:
57+
home: https://github.com/1minds3t/omnipkg
58+
license: AGPL-3.0-only
59+
license_family: AGPL
60+
license_file: LICENSE
61+
summary: 'The Ultimate Python Dependency Resolver. One environment. Infinite packages. Zero conflicts.'
62+
description: |
63+
OmniPkg is a distributed Python runtime hypervisor enabling concurrent,
64+
zero-copy multi-framework orchestration.
65+
66+
Platform Support:
67+
- Linux: x86_64, aarch64/ARM64, ppc64le
68+
- macOS: x86_64 (Intel), arm64 (Apple Silicon)
69+
- Windows: x86_64, ARM64
70+
71+
Key Features:
72+
- Microsecond package activation (~50μs)
73+
- Cross-platform daemon with native fork/no-fork modes
74+
- Concurrent multi-version package loading
75+
- Zero-copy multi-framework orchestration
76+
- Smart dependency resolution with snapshot restoration
77+
- Live daemon monitoring dashboard
78+
doc_url: https://omnipkg.readthedocs.io/en/latest/
79+
dev_url: https://github.com/1minds3t/omnipkg
80+
81+
extra:
82+
recipe-maintainers:
83+
- 1minds3t
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
{% set name = "omnipkg" %}
2+
{% set version = "2.0.7" %}
3+
4+
package:
5+
name: {{ name|lower }}
6+
version: {{ version }}
7+
8+
source:
9+
url: https://pypi.org/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz
10+
sha256: f07d3bd32e786e5de143b6e07558b1fe5ee1ab08ac701af3f98b8eb05bd8490b
11+
12+
build:
13+
number: 8 # Bump this!
14+
script:
15+
# Unix/Mac: Use the build python, but force install to the ARM location (${PREFIX})
16+
- python -m pip install . --no-deps --no-build-isolation --prefix "${PREFIX}" -vv # [unix]
17+
18+
# Windows: Just use standard pip (it knows where to go automatically)
19+
- python -m pip install . --no-deps --no-build-isolation -vv # [win]
20+
21+
entry_points:
22+
- omnipkg = omnipkg.cli:main
23+
- 8pkg = omnipkg.cli:main
24+
- 8PKG = omnipkg.cli:main
25+
- OMNIPKG = omnipkg.cli:main
26+
27+
requirements:
28+
build:
29+
- python # [build_platform != target_platform]
30+
- cross-python_{{ target_platform }} # [build_platform != target_platform]
31+
host:
32+
- python
33+
- pip
34+
- setuptools >=61.0
35+
run:
36+
- python
37+
- requests >=2.20
38+
- psutil >=5.9.0
39+
- typer >=0.4.0
40+
- rich >=10.0.0
41+
- filelock >=3.20.1
42+
- packaging >=23.0
43+
- tomli # [py<311]
44+
- authlib >=1.6.5
45+
- aiohttp >=3.13.1
46+
- safety >=3.7.0 # [py<314]
47+
- marshmallow >=4.1.2
48+
- pip-audit >=2.6.0 # [py>=314]
49+
- uv >=0.9.6 # [not ppc64le]
50+
- urllib3 >=1.26.19
51+
- tqdm >=4.67.1
52+
- typing-extensions >=4.0.0
53+
54+
test:
55+
# This selector skips tests when building osx-arm64 on an Intel runner
56+
requires:
57+
- pip
58+
imports:
59+
- omnipkg # [build_platform == target_platform]
60+
commands:
61+
- omnipkg --version # [build_platform == target_platform]
62+
63+
about:
64+
home: https://github.com/1minds3t/omnipkg
65+
license: AGPL-3.0-only
66+
license_family: AGPL
67+
license_file: LICENSE
68+
summary: 'The Ultimate Python Dependency Resolver. One environment. Infinite packages. Zero conflicts.'
69+
description: |
70+
OmniPkg is a distributed Python runtime hypervisor enabling concurrent,
71+
zero-copy multi-framework orchestration.
72+
73+
Platform Support:
74+
- Linux: x86_64, aarch64/ARM64, ppc64le
75+
- macOS: x86_64 (Intel), arm64 (Apple Silicon)
76+
- Windows: x86_64, ARM64
77+
78+
Key Features:
79+
- Microsecond package activation (~50μs)
80+
- Cross-platform daemon with native fork/no-fork modes
81+
- Concurrent multi-version package loading
82+
- Zero-copy multi-framework orchestration
83+
- Smart dependency resolution with snapshot restoration
84+
- Live daemon monitoring dashboard
85+
doc_url: https://omnipkg.readthedocs.io/en/latest/
86+
dev_url: https://github.com/1minds3t/omnipkg
87+
88+
extra:
89+
recipe-maintainers:
90+
- 1minds3t

0 commit comments

Comments
 (0)