mirror of
https://github.com/usestrix/strix.git
synced 2026-08-16 17:27:26 +02:00
Standalone macOS builds failed LLM preflight with a generic Connection error because cacert.pem was missing from the frozen bundle; also surface STRIX_DEBUG logs and exception cause chains before scan logging starts. Fixes #1008
285 lines
6.8 KiB
RPMSpec
285 lines
6.8 KiB
RPMSpec
# -*- mode: python ; coding: utf-8 -*-
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
from PyInstaller.utils.hooks import collect_data_files, collect_submodules
|
|
|
|
project_root = Path(SPECPATH)
|
|
strix_root = project_root / 'strix'
|
|
|
|
tui_name = 'strix-tui.exe' if sys.platform == 'win32' else 'strix-tui'
|
|
tui_binary = project_root / 'build' / 'sidecar' / tui_name
|
|
if not tui_binary.is_file():
|
|
raise FileNotFoundError(
|
|
f'Missing Go TUI sidecar at {tui_binary}; run `make tui-build` first'
|
|
)
|
|
binaries = [(str(tui_binary), 'strix/bin')]
|
|
|
|
datas = []
|
|
|
|
for md_file in strix_root.rglob('skills/**/*.md'):
|
|
rel_path = md_file.relative_to(project_root)
|
|
datas.append((str(md_file), str(rel_path.parent)))
|
|
|
|
for jinja_file in strix_root.rglob('agents/**/*.jinja'):
|
|
rel_path = jinja_file.relative_to(project_root)
|
|
datas.append((str(jinja_file), str(rel_path.parent)))
|
|
|
|
for xml_file in strix_root.rglob('*.xml'):
|
|
rel_path = xml_file.relative_to(project_root)
|
|
datas.append((str(xml_file), str(rel_path.parent)))
|
|
|
|
# Prebuilt local-viewer SPA (served by `strix view`).
|
|
viewer_static = strix_root / 'interface' / 'viewer' / 'static'
|
|
for asset in viewer_static.rglob('*'):
|
|
if asset.is_file():
|
|
rel_path = asset.relative_to(project_root)
|
|
datas.append((str(asset), str(rel_path.parent)))
|
|
|
|
datas += collect_data_files('tiktoken')
|
|
datas += collect_data_files('tiktoken_ext')
|
|
|
|
datas += collect_data_files('litellm')
|
|
# Frozen binaries need certifi's CA bundle on disk; without it TLS to LLM
|
|
# providers fails with a generic httpx/litellm "Connection error".
|
|
datas += collect_data_files('certifi')
|
|
|
|
datas += collect_data_files('agents', includes=['**/*.md', '**/*.jinja', '**/*.json'])
|
|
|
|
hiddenimports = [
|
|
# Core dependencies
|
|
'litellm',
|
|
'litellm.llms',
|
|
'litellm.llms.openai',
|
|
'litellm.llms.anthropic',
|
|
'litellm.llms.vertex_ai',
|
|
'litellm.llms.bedrock',
|
|
'litellm.utils',
|
|
'litellm.caching',
|
|
|
|
# Rich console
|
|
'rich',
|
|
'rich.console',
|
|
'rich.panel',
|
|
'rich.text',
|
|
'rich.markup',
|
|
'rich.style',
|
|
'rich.align',
|
|
'rich.live',
|
|
|
|
# Pydantic
|
|
'pydantic',
|
|
'pydantic.fields',
|
|
'pydantic_core',
|
|
'email_validator',
|
|
|
|
# Docker
|
|
'docker',
|
|
'docker.api',
|
|
'docker.models',
|
|
'docker.errors',
|
|
|
|
# HTTP/Networking
|
|
'httpx',
|
|
'httpcore',
|
|
'requests',
|
|
'urllib3',
|
|
'certifi',
|
|
|
|
# Jinja2 templating
|
|
'jinja2',
|
|
'jinja2.ext',
|
|
'markupsafe',
|
|
|
|
# XML parsing
|
|
'xmltodict',
|
|
'defusedxml',
|
|
'defusedxml.ElementTree',
|
|
|
|
# Syntax highlighting
|
|
'pygments',
|
|
'pygments.lexers',
|
|
'pygments.styles',
|
|
'pygments.util',
|
|
|
|
# Tiktoken (for token counting)
|
|
'tiktoken',
|
|
'tiktoken_ext',
|
|
'tiktoken_ext.openai_public',
|
|
|
|
# Tenacity retry
|
|
'tenacity',
|
|
|
|
# CVSS scoring
|
|
'cvss',
|
|
|
|
# Strix modules
|
|
'strix',
|
|
'strix.interface',
|
|
'strix.interface.main',
|
|
'strix.interface.cli',
|
|
'strix.interface.tui',
|
|
'strix.interface.tui.runtime',
|
|
'strix.interface.tui.history',
|
|
'strix.interface.tui.live_view',
|
|
'strix.interface.tui.backend',
|
|
'strix.interface.tui.backend.controller',
|
|
'strix.interface.tui.backend.messages',
|
|
'strix.interface.tui.backend.protocol',
|
|
'strix.interface.tui.backend.server',
|
|
'strix.interface.utils',
|
|
'strix.agents',
|
|
'strix.agents.factory',
|
|
'strix.agents.prompt',
|
|
'strix.config.loader',
|
|
'strix.config.settings',
|
|
'strix.config.codex',
|
|
'strix.core',
|
|
'strix.core.agents',
|
|
'strix.core.execution',
|
|
'strix.core.inputs',
|
|
'strix.core.paths',
|
|
'strix.core.runner',
|
|
'strix.core.sessions',
|
|
'strix.report',
|
|
'strix.report.dedupe',
|
|
'strix.report.state',
|
|
'strix.report.writer',
|
|
'strix.interface.viewer',
|
|
'strix.interface.viewer.auth',
|
|
'strix.interface.viewer.cli',
|
|
'strix.interface.viewer.report_pdf',
|
|
'strix.interface.viewer.server',
|
|
'strix.interface.viewer.transcript',
|
|
|
|
# PDF report generation + encryption
|
|
'reportlab',
|
|
'reportlab.pdfgen',
|
|
'reportlab.pdfbase',
|
|
'reportlab.lib',
|
|
'reportlab.platypus',
|
|
'pypdf',
|
|
'cryptography',
|
|
'strix.runtime',
|
|
'strix.runtime.backends',
|
|
'strix.runtime.caido_bootstrap',
|
|
'strix.runtime.docker_client',
|
|
'strix.runtime.session_manager',
|
|
'strix.telemetry',
|
|
'strix.telemetry.logging',
|
|
'strix.telemetry.posthog',
|
|
'strix.tools',
|
|
'strix.tools.agents_graph.tools',
|
|
'strix.tools.finish.tool',
|
|
'strix.tools.notes.tools',
|
|
'strix.tools.proxy._calls',
|
|
'strix.tools.proxy.tools',
|
|
'strix.tools.python.tool',
|
|
'strix.tools.reporting.tool',
|
|
'strix.tools.thinking.tool',
|
|
'strix.tools.todo.tools',
|
|
'strix.tools.web_search.tool',
|
|
'strix.skills',
|
|
]
|
|
|
|
hiddenimports += collect_submodules('litellm')
|
|
hiddenimports += collect_submodules('rich')
|
|
hiddenimports += collect_submodules('pydantic')
|
|
hiddenimports += collect_submodules('pygments')
|
|
# reportlab loads renderers/fonts dynamically, so pull its whole tree in.
|
|
hiddenimports += collect_submodules('reportlab')
|
|
|
|
# reportlab ships bundled fonts (.pfb/.afm) it needs at runtime.
|
|
datas += collect_data_files('reportlab')
|
|
|
|
# reportlab imports PIL (pillow) lazily for image handling, so it must be
|
|
# bundled explicitly and kept out of the excludes list below.
|
|
hiddenimports += collect_submodules('PIL')
|
|
datas += collect_data_files('PIL')
|
|
|
|
excludes = [
|
|
# Sandbox-only packages
|
|
'playwright',
|
|
'playwright.sync_api',
|
|
'playwright.async_api',
|
|
'IPython',
|
|
'ipython',
|
|
'libtmux',
|
|
'pyte',
|
|
'openhands_aci',
|
|
'openhands-aci',
|
|
'numpydoc',
|
|
|
|
# Google Cloud / Vertex AI
|
|
'google.cloud',
|
|
'google.cloud.aiplatform',
|
|
'google.api_core',
|
|
'google.auth',
|
|
'google.oauth2',
|
|
'google.protobuf',
|
|
'grpc',
|
|
'grpcio',
|
|
'grpcio_status',
|
|
|
|
# Test frameworks
|
|
'pytest',
|
|
'pytest_asyncio',
|
|
'pytest_cov',
|
|
'pytest_mock',
|
|
|
|
# Development tools
|
|
'mypy',
|
|
'ruff',
|
|
'black',
|
|
'isort',
|
|
'pylint',
|
|
'pyright',
|
|
'bandit',
|
|
'pre_commit',
|
|
|
|
# Unnecessary for runtime
|
|
'tkinter',
|
|
'matplotlib',
|
|
'numpy',
|
|
'pandas',
|
|
'scipy',
|
|
'cv2',
|
|
]
|
|
|
|
a = Analysis(
|
|
['strix/interface/main.py'],
|
|
pathex=[str(project_root)],
|
|
binaries=binaries,
|
|
datas=datas,
|
|
hiddenimports=hiddenimports,
|
|
hookspath=[],
|
|
hooksconfig={},
|
|
runtime_hooks=[str(project_root / 'hooks' / 'rthooks' / 'pyi_rth_certifi.py')],
|
|
excludes=excludes,
|
|
noarchive=False,
|
|
optimize=0,
|
|
)
|
|
|
|
pyz = PYZ(a.pure)
|
|
|
|
exe = EXE(
|
|
pyz,
|
|
a.scripts,
|
|
a.binaries,
|
|
a.datas,
|
|
[],
|
|
name='strix',
|
|
debug=False,
|
|
bootloader_ignore_signals=False,
|
|
strip=False,
|
|
upx=False,
|
|
upx_exclude=[],
|
|
runtime_tmpdir=None,
|
|
console=True,
|
|
disable_windowed_traceback=False,
|
|
argv_emulation=False,
|
|
target_arch=None,
|
|
codesign_identity=None,
|
|
entitlements_file=None,
|
|
)
|