local-operator-ui 0.18.0 → 0.19.1
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/out/main/index.js +240 -16
- package/out/renderer/assets/{_basePickBy-CZFZb5JR.js → _basePickBy-ykG0NPFf.js} +1 -1
- package/out/renderer/assets/{_baseUniq-DdA2opXA.js → _baseUniq-zF370IN-.js} +1 -1
- package/out/renderer/assets/{agent-details-page-CUVk_dQA.js → agent-details-page-CFeQgmpk.js} +1 -1
- package/out/renderer/assets/{agent-hub-page-9yyeW__o.js → agent-hub-page-WTDOpgeF.js} +1 -1
- package/out/renderer/assets/{agents-page-jV0apiGh.js → agents-page-BcpOVq5W.js} +2 -2
- package/out/renderer/assets/{architectureDiagram-IEHRJDOE-CVRNNZJF.js → architectureDiagram-IEHRJDOE-BgE-rKS0.js} +1 -1
- package/out/renderer/assets/{blockDiagram-JOT3LUYC-BFw8sjPz.js → blockDiagram-JOT3LUYC-fcZbaNLm.js} +1 -1
- package/out/renderer/assets/{c4Diagram-VJAJSXHY-BlvUMlkS.js → c4Diagram-VJAJSXHY-DECLed3f.js} +1 -1
- package/out/renderer/assets/channel-CsUT-bgQ.js +1 -0
- package/out/renderer/assets/{chunk-4BMEZGHF-DmmHenbb.js → chunk-4BMEZGHF-CCYSb0Fh.js} +1 -1
- package/out/renderer/assets/{chunk-A2AXSNBT-C-YVsTUA.js → chunk-A2AXSNBT-CjRtRikA.js} +1 -1
- package/out/renderer/assets/{chunk-AEK57VVT-Cd4FhOet.js → chunk-AEK57VVT-eVeRvEm8.js} +1 -1
- package/out/renderer/assets/{chunk-D6G4REZN-Wwb68FpB.js → chunk-D6G4REZN-BN7tXfjV.js} +1 -1
- package/out/renderer/assets/{chunk-RZ5BOZE2-DrR7FO6O.js → chunk-RZ5BOZE2-hZ_ZoDPs.js} +1 -1
- package/out/renderer/assets/{chunk-XZIHB7SX-B8-klKjT.js → chunk-XZIHB7SX-LDikEfMz.js} +1 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-8XRUpU40.js +1 -0
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-8XRUpU40.js +1 -0
- package/out/renderer/assets/clone-BTzCuJ8z.js +1 -0
- package/out/renderer/assets/{compact-pagination-eBVrbCvF.js → compact-pagination-DqiXMGmM.js} +1 -1
- package/out/renderer/assets/{dagre-OKDRZEBW-C6qz5RYl.js → dagre-OKDRZEBW-f4DSNbNt.js} +1 -1
- package/out/renderer/assets/{diagram-SSKATNLV-Bi85yZmy.js → diagram-SSKATNLV-DFy9Kjn5.js} +1 -1
- package/out/renderer/assets/{diagram-VNBRO52H-Bl3QigUL.js → diagram-VNBRO52H-DxfeD-Xq.js} +1 -1
- package/out/renderer/assets/{erDiagram-Q7BY3M3F-BxkWhjhD.js → erDiagram-Q7BY3M3F-BKIiiDiS.js} +1 -1
- package/out/renderer/assets/{flowDiagram-4HSFHLVR-Ftod-Xm4.js → flowDiagram-4HSFHLVR-bPQ65Vad.js} +1 -1
- package/out/renderer/assets/{ganttDiagram-APWFNJXF-Be2oW9_3.js → ganttDiagram-APWFNJXF-B4QAAaiA.js} +1 -1
- package/out/renderer/assets/{gitGraphDiagram-7IBYFJ6S-Cq0io_7G.js → gitGraphDiagram-7IBYFJ6S-CKw3yJdA.js} +1 -1
- package/out/renderer/assets/{graph--CsZfsc1.js → graph-BQE_YPzn.js} +1 -1
- package/out/renderer/assets/{icon-DmLp2A4T.js → icon-BjW36U6M.js} +30 -30
- package/out/renderer/assets/icon-BsCMUQ0p.css +1 -0
- package/out/renderer/assets/{index-Bg2SkTsx.js → index-Byb6o6Kr.js} +334 -308
- package/out/renderer/assets/{index-BjwY_ASt.js → index-Cv1VxdCo.js} +1 -1
- package/out/renderer/assets/{index-BA_sFfzi.js → index-lnppTSlu.js} +1 -1
- package/out/renderer/assets/{infoDiagram-PH2N3AL5-DkLRhq8W.js → infoDiagram-PH2N3AL5-dZAW4pJY.js} +1 -1
- package/out/renderer/assets/{installer-CiGz2A-K.js → installer-CIexauct.js} +1 -1
- package/out/renderer/assets/{journeyDiagram-U35MCT3I-BJetGa52.js → journeyDiagram-U35MCT3I-Bfaldm3O.js} +1 -1
- package/out/renderer/assets/{kanban-definition-NDS4AKOZ-5fG21OZ8.js → kanban-definition-NDS4AKOZ-BihrMyrx.js} +1 -1
- package/out/renderer/assets/{layout-B2XKA-jM.js → layout-BY0TgmPG.js} +1 -1
- package/out/renderer/assets/{legacy-agents-page-DcQ5jHNu.js → legacy-agents-page-nTvYG2R1.js} +1 -1
- package/out/renderer/assets/{mermaid.core-BpGCpBxO.js → mermaid.core-C_9cdmTh.js} +5 -5
- package/out/renderer/assets/{mindmap-definition-ALO5MXBD-r1Asg5Tr.js → mindmap-definition-ALO5MXBD-DGcjfOea.js} +1 -1
- package/out/renderer/assets/{page-header-omBUxnjS.js → page-header-DwrySHPp.js} +1 -1
- package/out/renderer/assets/{parseISO-E6hIBnDI.js → parseISO-Nf075j_I.js} +1 -1
- package/out/renderer/assets/{pieDiagram-IB7DONF6-0TYkoY-4.js → pieDiagram-IB7DONF6-CLQQsy4S.js} +1 -1
- package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-CoolIPz7.js → quadrantDiagram-7GDLP6J5-BW18K7e-.js} +1 -1
- package/out/renderer/assets/{radar-MK3ICKWK-D_opGmu3.js → radar-MK3ICKWK-D5qSNCES.js} +1 -1
- package/out/renderer/assets/{radient-auth-buttons-GBy9g6wz.js → radient-auth-buttons-C68jw6Rq.js} +1 -1
- package/out/renderer/assets/{requirementDiagram-KVF5MWMF-DNbOx5SX.js → requirementDiagram-KVF5MWMF-BGO78UpF.js} +1 -1
- package/out/renderer/assets/{sankeyDiagram-QLVOVGJD-Dh2Ng2tU.js → sankeyDiagram-QLVOVGJD-D10GCyqA.js} +1 -1
- package/out/renderer/assets/{schedules-page-CN0GZwcz.js → schedules-page-BhoAmrxA.js} +1 -1
- package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-BS1YnbjH.js → sequenceDiagram-X6HHIX6F-DJ0J92CL.js} +1 -1
- package/out/renderer/assets/{settings-page-DuSK5S6i.js → settings-page-7W7M_FIE.js} +1 -1
- package/out/renderer/assets/{square-pen-BoZxUPzv.js → square-pen-D9Eba1sr.js} +1 -1
- package/out/renderer/assets/{stateDiagram-DGXRK772-I0EgfDwZ.js → stateDiagram-DGXRK772-BRFGcjMT.js} +1 -1
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-BYuk7Mif.js +1 -0
- package/out/renderer/assets/{timeline-definition-BDJGKUSR-Ko7ZTCqE.js → timeline-definition-BDJGKUSR-V2afOmNy.js} +1 -1
- package/out/renderer/assets/{use-agent-like-mutation-gvVXz8X9.js → use-agent-like-mutation-CS4DoZ5N.js} +1 -1
- package/out/renderer/assets/{xychartDiagram-VJFVF3MP-Cumv03Gu.js → xychartDiagram-VJFVF3MP-DSF1yRSG.js} +1 -1
- package/out/renderer/index.html +3 -3
- package/out/renderer/installer.html +3 -3
- package/package.json +2 -2
- package/out/renderer/assets/channel-N-w2RP4J.js +0 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-dKb30qTt.js +0 -1
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-dKb30qTt.js +0 -1
- package/out/renderer/assets/clone-IRDG1lZO.js +0 -1
- package/out/renderer/assets/icon-D2_8erEx.css +0 -1
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-jP5EH-Qa.js +0 -1
package/out/main/index.js
CHANGED
|
@@ -1323,6 +1323,19 @@ function trustedDesktopFrame(actual, expected) {
|
|
|
1323
1323
|
return false;
|
|
1324
1324
|
}
|
|
1325
1325
|
}
|
|
1326
|
+
const PYTHON_BYTECODE_CACHE_DIR_NAME = "python-bytecode-cache";
|
|
1327
|
+
const PATH_SEPARATORS = /[\\/]/;
|
|
1328
|
+
function insideAppBundle(path2) {
|
|
1329
|
+
return path2.split(PATH_SEPARATORS).some((segment) => segment.length > 4 && segment.endsWith(".app"));
|
|
1330
|
+
}
|
|
1331
|
+
function pythonBytecodeCacheDir(userDataDir) {
|
|
1332
|
+
return path.join(userDataDir, PYTHON_BYTECODE_CACHE_DIR_NAME);
|
|
1333
|
+
}
|
|
1334
|
+
function withPythonBytecodeCache(env, userDataDir) {
|
|
1335
|
+
const existing = env.PYTHONPYCACHEPREFIX?.trim();
|
|
1336
|
+
if (existing && !insideAppBundle(existing)) return { ...env };
|
|
1337
|
+
return { ...env, PYTHONPYCACHEPREFIX: pythonBytecodeCacheDir(userDataDir) };
|
|
1338
|
+
}
|
|
1326
1339
|
var main = { exports: {} };
|
|
1327
1340
|
const version = "16.5.0";
|
|
1328
1341
|
const require$$4 = {
|
|
@@ -1989,6 +2002,7 @@ class BackendServiceManager {
|
|
|
1989
2002
|
`Shell environment variables loaded successfully. PATH: ${this.shellEnv.PATH || this.shellEnv.Path || "(not set)"}`,
|
|
1990
2003
|
LogFileType.BACKEND
|
|
1991
2004
|
);
|
|
2005
|
+
this.shellEnv = withPythonBytecodeCache(this.shellEnv, this.appDataPath);
|
|
1992
2006
|
} catch (error) {
|
|
1993
2007
|
logger.error(
|
|
1994
2008
|
"Error loading shell environment variables:",
|
|
@@ -1997,6 +2011,34 @@ class BackendServiceManager {
|
|
|
1997
2011
|
);
|
|
1998
2012
|
}
|
|
1999
2013
|
}
|
|
2014
|
+
/**
|
|
2015
|
+
* The environment the backend process is spawned with.
|
|
2016
|
+
*
|
|
2017
|
+
* The prefix is applied HERE, at the point the environment is handed to the
|
|
2018
|
+
* spawn, rather than only inside `loadShellEnvironment()`. That load is
|
|
2019
|
+
* started from the constructor without `await` (a constructor cannot wait)
|
|
2020
|
+
* and `start()` has nothing sequencing it, so a shell rc that takes seconds
|
|
2021
|
+
* to source - nvm, pyenv, conda init all do - leaves `shellEnv` at its
|
|
2022
|
+
* `{ ...process.env }` seed when the first spawn happens: no prefix, and the
|
|
2023
|
+
* exact pre-fix configuration, on the machines whose rc is slowest. Applying
|
|
2024
|
+
* it here makes the guarantee structural instead of ordering-dependent, so
|
|
2025
|
+
* no spawn path can miss it.
|
|
2026
|
+
*
|
|
2027
|
+
* These spawns are the ones whose `python` is the interpreter we ship:
|
|
2028
|
+
* CPython writes `__pycache__/*.pyc` beside the sources it imports, those
|
|
2029
|
+
* sources are inside the code-sealed `.app`, and every such write breaks the
|
|
2030
|
+
* signature ShipIt validates before an in-place update.
|
|
2031
|
+
*/
|
|
2032
|
+
backendSpawnEnv() {
|
|
2033
|
+
return {
|
|
2034
|
+
...withPythonBytecodeCache(this.shellEnv, this.appDataPath),
|
|
2035
|
+
// Managed starts rotate the token; set after the spread so the spawn
|
|
2036
|
+
// can never inherit a stale one from the shell environment. `start()`
|
|
2037
|
+
// mints it before it can reach a spawn site, so the `??` only satisfies
|
|
2038
|
+
// the field's nullable seed from `process.env`.
|
|
2039
|
+
LOCAL_OPERATOR_DESKTOP_TOKEN: this.desktopToken ?? void 0
|
|
2040
|
+
};
|
|
2041
|
+
}
|
|
2000
2042
|
/**
|
|
2001
2043
|
* Load environment variables from macOS shell configuration files
|
|
2002
2044
|
*/
|
|
@@ -2315,10 +2357,7 @@ class BackendServiceManager {
|
|
|
2315
2357
|
detached: false,
|
|
2316
2358
|
// Ensure process is not detached from parent
|
|
2317
2359
|
stdio: "pipe",
|
|
2318
|
-
env:
|
|
2319
|
-
...this.shellEnv,
|
|
2320
|
-
LOCAL_OPERATOR_DESKTOP_TOKEN: this.desktopToken
|
|
2321
|
-
},
|
|
2360
|
+
env: this.backendSpawnEnv(),
|
|
2322
2361
|
// On Windows, we need to create a new process group to ensure proper termination
|
|
2323
2362
|
...process.platform === "win32" ? { windowsHide: true } : {}
|
|
2324
2363
|
});
|
|
@@ -2381,10 +2420,7 @@ class BackendServiceManager {
|
|
|
2381
2420
|
detached: false,
|
|
2382
2421
|
// Ensure process is not detached from parent
|
|
2383
2422
|
stdio: "pipe",
|
|
2384
|
-
env:
|
|
2385
|
-
...this.shellEnv,
|
|
2386
|
-
LOCAL_OPERATOR_DESKTOP_TOKEN: this.desktopToken
|
|
2387
|
-
},
|
|
2423
|
+
env: this.backendSpawnEnv(),
|
|
2388
2424
|
// On Windows, we need to create a new process group to ensure proper termination
|
|
2389
2425
|
...process.platform === "win32" ? { windowsHide: true } : {}
|
|
2390
2426
|
});
|
|
@@ -2818,7 +2854,7 @@ class BackendServiceManager {
|
|
|
2818
2854
|
return success;
|
|
2819
2855
|
}
|
|
2820
2856
|
}
|
|
2821
|
-
const linuxInstallScriptRaw = '#!/bin/bash\n# Local Operator Backend Installation Script for Linux\n# This script sets up a virtual environment for the Local Operator backend\n# without requiring sudo or admin privileges.\n\n# Exit on error, undefined variables, and failed pipe commands\nset -e # Exit immediately if a command exits with a non-zero status\nset -u # Error on unset variables\nset -o pipefail # Fail if any command in a pipe fails\n\n# Configuration\n# Variables APP_NAME and MIN_PYTHON_VERSION removed as they were unused\nVENV_NAME="local-operator-venv"\nAPP_DATA_DIR="${HOME}/.config/local-operator"\nVENV_PATH="${APP_DATA_DIR}/${VENV_NAME}"\nLOG_FILE="${APP_DATA_DIR}/backend-install.log"\nTIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")\n\n# Create app data directory if it doesn\'t exist\nif ! mkdir -p "${APP_DATA_DIR}"; then\n echo "ERROR: Unable to create app data directory at ${APP_DATA_DIR}"\n echo "Please check permissions and try again."\n exit 1\nfi\n\n# Handle cleanup on script exit\ncleanup() {\n # Remove any temporary files created during execution\n if [ -f "${APP_DATA_DIR}/get-pip.py" ]; then\n rm -f "${APP_DATA_DIR}/get-pip.py"\n fi\n if [ -n "${FFMPEG_TEMP_ARCHIVE:-}" ] && [ -f "${FFMPEG_TEMP_ARCHIVE}" ]; then\n log "Removing temporary FFmpeg archive: ${FFMPEG_TEMP_ARCHIVE}"\n rm -f "${FFMPEG_TEMP_ARCHIVE}"\n fi\n echo "$(date): Cleanup completed."\n}\n\n# Set trap only for manual interruption (SIGINT, SIGTERM), not normal exits\ntrap cleanup SIGINT SIGTERM\n\n\n# Start logging\nexec > >(tee -a "${LOG_FILE}") 2>&1\necho "[${TIMESTAMP}]: Starting Local Operator backend installation..."\necho "[${TIMESTAMP}]: System information: $(uname -a)"\n\n# Function to log messages with timestamp (defined later, but used by FFmpeg section)\n_log_internal() {\n local internal_timestamp\n internal_timestamp=$(date +"%Y-%m-%d %H:%M:%S")\n echo "[${internal_timestamp}] $1"\n}\n\n# --- FFmpeg Installation ---\nBIN_DIR="${APP_DATA_DIR}/bin"\nFFMPEG_BIN="${BIN_DIR}/ffmpeg" # Path to ffmpeg binary\n\n_log_internal "Ensuring bin directory exists: ${BIN_DIR}"\nif ! mkdir -p "${BIN_DIR}"; then\n _log_internal "ERROR: Unable to create bin directory at ${BIN_DIR}"\n exit 1\nfi\n\n# Check if FFmpeg is already installed and executable\nif [ -f "${FFMPEG_BIN}" ] && [ -x "${FFMPEG_BIN}" ]; then\n _log_internal "FFmpeg already installed at ${FFMPEG_BIN}. Skipping download."\nelse\n _log_internal "FFmpeg not found or not executable. Attempting to download and install FFmpeg..."\n\n FFMPEG_DOWNLOAD_URL=""\n\n LINUX_ARCH=$(uname -m)\n if [[ "${LINUX_ARCH}" == "x86_64" ]]; then\n FFMPEG_DOWNLOAD_URL="https://github.com/eugeneware/ffmpeg-static/releases/download/b6.0/ffmpeg-linux-x64"\n elif [[ "${LINUX_ARCH}" == "aarch64" ]] || [[ "${LINUX_ARCH}" == "arm64" ]]; then\n FFMPEG_DOWNLOAD_URL="https://github.com/eugeneware/ffmpeg-static/releases/download/b6.0/ffmpeg-linux-arm64"\n else\n _log_internal "Error: Unsupported CPU architecture for FFmpeg download: ${LINUX_ARCH}"\n exit 1\n fi\n\n _log_internal "Downloading FFmpeg from: ${FFMPEG_DOWNLOAD_URL}"\n if command -v curl >/dev/null 2>&1; then\n if ! curl -L "${FFMPEG_DOWNLOAD_URL}" -o "${FFMPEG_BIN}"; then\n _log_internal "Error: Failed to download FFmpeg using curl from ${FFMPEG_DOWNLOAD_URL}"\n exit 1\n fi\n elif command -v wget >/dev/null 2>&1; then\n if ! wget -O "${FFMPEG_BIN}" "${FFMPEG_DOWNLOAD_URL}"; then\n _log_internal "Error: Failed to download FFmpeg using wget from ${FFMPEG_DOWNLOAD_URL}"\n exit 1\n fi\n else\n _log_internal "Error: Neither curl nor wget found. Cannot download FFmpeg."\n exit 1\n fi\n _log_internal "FFmpeg binary downloaded successfully to ${FFMPEG_BIN}"\n\n chmod +x "${FFMPEG_BIN}"\n _log_internal "Set executable permissions for ${FFMPEG_BIN}"\n\n # Verify FFmpeg is executable after download\n if [ ! -f "${FFMPEG_BIN}" ] || [ ! -x "${FFMPEG_BIN}" ]; then\n _log_internal "Error: FFmpeg binary not found or not executable after download."\n exit 1\n fi\nfi\n\n_log_internal "FFmpeg installation complete. FFmpeg binary is at: ${FFMPEG_BIN}"\n\n# Function to check if a command exists\ncommand_exists() {\n command -v "$1" >/dev/null 2>&1\n}\n\n# Function to log messages with timestamp\nlog() {\n local timestamp\n timestamp=$(date +"%Y-%m-%d %H:%M:%S")\n echo "[${timestamp}] $1"\n}\n\n# Function to display error messages and exit\nerror_exit() {\n log "ERROR: $1" >&2\n exit "${2:-1}"\n}\n\n# Function to check if Python binary is valid for current architecture\nis_valid_python_binary() {\n local python_path="$1"\n \n # First check if file exists and is executable\n if [ ! -f "${python_path}" ] || [ ! -x "${python_path}" ]; then\n return 1\n fi\n \n # Try to run a simple Python command to verify it works on current architecture\n "${python_path}" -c "print(\'Testing Python executable\')" >/dev/null 2>&1\n return $?\n}\n\n# Check for network connectivity to key servers\ncheck_connectivity() {\n log "Checking network connectivity..."\n local servers=("pypi.org" "bootstrap.pypa.io")\n local has_connectivity=false\n \n for server in "${servers[@]}"; do\n if command_exists curl; then\n if curl --connect-timeout 5 -s "https://${server}" -o /dev/null; then\n has_connectivity=true\n break\n fi\n elif command_exists wget; then\n if wget --timeout=5 -q --spider "https://${server}"; then\n has_connectivity=true\n break\n fi\n fi\n done\n \n if [ "$has_connectivity" = false ]; then\n log "WARNING: Network connectivity issues detected. This may affect installation."\n else\n log "Network connectivity confirmed."\n fi\n}\n\n# Call connectivity check\ncheck_connectivity\n\n# Check if PYTHON_BIN is already set by the installer\nif [ -n "${PYTHON_BIN:-}" ]; then\n log "Using Python executable provided by installer: ${PYTHON_BIN}"\n # Verify the provided Python binary works on this architecture\n if ! is_valid_python_binary "${PYTHON_BIN}"; then\n log "Warning: The provided Python binary is not compatible with this system architecture."\n log "Will attempt to find a system Python installation instead."\n PYTHON_BIN=""\n fi\nfi\n\n# If PYTHON_BIN is empty or invalid, try to find a suitable Python installation\nif [ -z "${PYTHON_BIN:-}" ] || ! is_valid_python_binary "${PYTHON_BIN:-}"; then\n # Try to find a suitable Python installation\n log "Looking for a suitable Python installation..."\n \n # Try multiple possible locations to find Python\n POSSIBLE_PYTHON_PATHS=(\n # System paths first (more likely to be compatible with current architecture)\n "/usr/local/bin/python3.12"\n "/usr/bin/python3.12"\n "/usr/local/bin/python3"\n "/usr/bin/python3"\n # From environment variable (set by the installer)\n "${ELECTRON_RESOURCE_PATH:-}/python/bin/python3"\n # Development paths\n "$(dirname "$0")/../../../resources/python/bin/python3"\n "$(pwd)/resources/python/bin/python3"\n )\n\n # Find the first Python that exists and is version 3.12+ and works on this architecture\n PYTHON_BIN=""\n for path in "${POSSIBLE_PYTHON_PATHS[@]}"; do\n # Skip empty paths that might come from unset environment variables\n if [ -z "${path}" ]; then\n continue\n fi\n \n if is_valid_python_binary "${path}"; then\n # Check Python version\n if PY_VERSION=$("${path}" -c "import sys; print(f\'{sys.version_info.major}.{sys.version_info.minor}\')" 2>/dev/null); then\n MAJOR=$(echo "${PY_VERSION}" | cut -d. -f1)\n MINOR=$(echo "${PY_VERSION}" | cut -d. -f2)\n if [ "${MAJOR}" -eq 3 ] && [ "${MINOR}" -ge 12 ]; then\n PYTHON_BIN="${path}"\n log "Found suitable Python ${PY_VERSION} at ${path}"\n break\n else\n log "Python at ${path} is version ${PY_VERSION}, which is below the required 3.12+"\n fi\n fi\n else\n if [ -f "${path}" ]; then\n log "Python at ${path} exists but is not compatible with this system architecture"\n fi\n fi\n done\n\n # If we couldn\'t find a suitable Python, exit with error\n if [ -z "${PYTHON_BIN:-}" ]; then\n error_exit "No suitable Python installation found (version 3.12 or higher required).\\nPlease install Python 3.12 or higher before running this script.\\nYou can install Python from https://www.python.org/downloads/"\n fi\nfi\n\necho "Using Python: $PYTHON_BIN"\n"$PYTHON_BIN" --version || {\n echo "Error: Failed to run Python. Please ensure it is executable and accessible."\n echo "System architecture: $(uname -m)"\n echo "Python binary architecture: $(file "$PYTHON_BIN" 2>/dev/null || echo \'Unable to determine\')"\n exit 1\n}\n\n# Detect the Linux distribution to provide specific instructions\nif command_exists lsb_release; then\n DISTRO=$(lsb_release -is)\n DISTRO_VERSION=$(lsb_release -rs)\n echo "Detected Linux distribution: $DISTRO $DISTRO_VERSION"\nelif [ -f /etc/os-release ]; then\n DISTRO=$(grep -oP \'(?<=^ID=).+\' /etc/os-release | tr -d \'"\')\n DISTRO_VERSION=$(grep -oP \'(?<=^VERSION_ID=).+\' /etc/os-release | tr -d \'"\')\n echo "Detected Linux distribution: $DISTRO $DISTRO_VERSION"\nelse\n DISTRO="unknown"\n echo "Unable to detect Linux distribution"\nfi\n\n# Check if Python has venv module and ensurepip available\nlog "Checking for venv module and ensurepip availability..."\nVENV_AVAILABLE=0\nENSUREPIP_AVAILABLE=0\n\n"${PYTHON_BIN}" -c "import venv" > /dev/null 2>&1 || VENV_AVAILABLE=1\n"${PYTHON_BIN}" -c "import ensurepip" > /dev/null 2>&1 || ENSUREPIP_AVAILABLE=1\n\n# If venv is still not available, try to use virtualenv as a fallback\nif [ $VENV_AVAILABLE -ne 0 ]; then\n echo "venv module is not available. Checking for virtualenv as an alternative..."\n \n # Check if virtualenv is already installed\n if "$PYTHON_BIN" -c "import virtualenv" > /dev/null 2>&1; then\n echo "virtualenv is available, will use it instead of venv"\n else\n echo "ERROR: Neither venv nor virtualenv is available."\n echo "Python 3.12 and venv should be installed as package dependencies."\n echo "Please ensure Python 3.12 and venv are properly installed on your system."\n exit 1\n fi\nfi\n\n# Create virtual environment if it doesn\'t exist\nif [ ! -d "$VENV_PATH" ]; then\n echo "Creating virtual environment at $VENV_PATH..."\n # Remove any potentially corrupted virtual environment\n if [ -e "$VENV_PATH" ]; then\n echo "Removing existing but potentially corrupted venv directory..."\n rm -rf "$VENV_PATH"\n fi\n \n # Make sure parent directory exists and is writable\n mkdir -p "$(dirname "$VENV_PATH")"\n \n # Try different methods to create a virtual environment\n VENV_CREATE_STATUS=1\n \n # First try with venv if available\n if [ $VENV_AVAILABLE -eq 0 ] && [ $ENSUREPIP_AVAILABLE -eq 0 ]; then\n echo "Creating virtual environment using venv module..."\n "$PYTHON_BIN" -m venv "$VENV_PATH"\n VENV_CREATE_STATUS=$?\n fi\n \n # If venv failed, try virtualenv\n if [ $VENV_CREATE_STATUS -ne 0 ]; then\n echo "venv creation failed with status $VENV_CREATE_STATUS. Falling back to virtualenv..."\n if command_exists virtualenv; then\n virtualenv -p "$PYTHON_BIN" "$VENV_PATH"\n VENV_CREATE_STATUS=$?\n elif "$PYTHON_BIN" -m pip list | grep -q virtualenv; then\n "$PYTHON_BIN" -m virtualenv -p "$PYTHON_BIN" "$VENV_PATH"\n VENV_CREATE_STATUS=$?\n else\n echo "ERROR: Both venv and virtualenv are unavailable or failed."\n echo "Python 3.12 and venv should be installed as package dependencies."\n echo "Please ensure Python 3.12 and venv are properly installed on your system."\n echo "You can install Python 3.12 from https://www.python.org/downloads/"\n exit 1\n fi\n fi\n \n # Check if virtual environment creation was successful\n if [ $VENV_CREATE_STATUS -ne 0 ]; then\n log "ERROR: Failed to create virtual environment. Exit code: $VENV_CREATE_STATUS"\n log "Virtual environment path: $VENV_PATH"\n log "Python binary used: $PYTHON_BIN"\n ls -la "$(dirname "$VENV_PATH")" || true\n log "Python executable permissions:"\n ls -la "$PYTHON_BIN" || true\n \n # Check for common issues\n log "Checking for common virtual environment creation issues..."\n \n # Check disk space\n df -h "$(dirname "$VENV_PATH")" || true\n \n # Check if directory is writable\n if [ ! -w "$(dirname "$VENV_PATH")" ]; then\n log "ERROR: Directory $(dirname "$VENV_PATH") is not writable"\n fi\n \n # Try to create a minimal virtual environment manually as a last resort\n log "Attempting to create a minimal virtual environment manually..."\n mkdir -p "$VENV_PATH/bin" || error_exit "Could not create directory $VENV_PATH/bin"\n echo "#!/bin/bash" > "$VENV_PATH/bin/activate"\n echo "export VIRTUAL_ENV=\\"$VENV_PATH\\"" >> "$VENV_PATH/bin/activate"\n echo "export PATH=\\"$VENV_PATH/bin:\\$PATH\\"" >> "$VENV_PATH/bin/activate"\n echo "unset PYTHONHOME" >> "$VENV_PATH/bin/activate"\n chmod +x "$VENV_PATH/bin/activate" || error_exit "Could not set execute permissions on activate script"\n \n # Create symlinks to the system Python\n ln -sf "$PYTHON_BIN" "$VENV_PATH/bin/python" || log "WARNING: Failed to create symlink for python"\n ln -sf "$PYTHON_BIN" "$VENV_PATH/bin/python3" || log "WARNING: Failed to create symlink for python3"\n \n # Try to bootstrap pip\n log "Bootstrapping pip in the minimal virtual environment..."\n if command_exists curl; then\n curl -s https://bootstrap.pypa.io/get-pip.py -o "$APP_DATA_DIR/get-pip.py" || log "WARNING: Failed to download get-pip.py"\n elif command_exists wget; then\n wget -q -O "$APP_DATA_DIR/get-pip.py" https://bootstrap.pypa.io/get-pip.py || log "WARNING: Failed to download get-pip.py"\n else\n log "ERROR: Neither curl nor wget available to download get-pip.py"\n error_exit "Installation cannot continue without being able to download pip"\n fi\n \n # shellcheck disable=SC1090\n source "$VENV_PATH/bin/activate" && python "$APP_DATA_DIR/get-pip.py" --no-warn-script-location\n \n if [ ! -f "$VENV_PATH/bin/pip" ]; then\n error_exit "Failed to create even a minimal virtual environment."\n else\n log "Created a minimal virtual environment as a fallback."\n fi\n else\n log "Successfully created virtual environment"\n fi\nfi\n\n# Verify the virtual environment structure\necho "Verifying virtual environment structure..."\nif [ ! -f "$VENV_PATH/bin/python" ]; then\n echo "Python executable missing in virtual environment, creating symlink..."\n ln -sf "$PYTHON_BIN" "$VENV_PATH/bin/python"\nfi\n\nif [ ! -f "$VENV_PATH/bin/pip" ]; then\n echo "pip missing in virtual environment, attempting to bootstrap it..."\n curl -s https://bootstrap.pypa.io/get-pip.py -o "$APP_DATA_DIR/get-pip.py"\n "$VENV_PATH/bin/python" "$APP_DATA_DIR/get-pip.py" --no-warn-script-location\n \n if [ ! -f "$VENV_PATH/bin/pip" ]; then\n echo "ERROR: Failed to bootstrap pip in the virtual environment"\n exit 1\n fi\nfi\n\necho "Virtual environment structure verified"\n\n# Activate virtual environment and install local-operator\necho "Installing local-operator in virtual environment..."\nsource "$VENV_PATH/bin/activate"\n\necho "Upgrading pip..."\npython -m pip install --upgrade pip || {\n echo "WARNING: Failed to upgrade pip. Will try to continue with existing pip version."\n pip --version\n}\n\n# Check network connectivity to PyPI\necho "Checking network connectivity to PyPI..."\nif command_exists curl; then\n curl -s https://pypi.org/pypi/local-operator/json -o /dev/null || {\n echo "WARNING: Could not reach PyPI. Network connectivity issues might prevent installation."\n }\nelif command_exists wget; then\n wget -q --spider https://pypi.org/pypi/local-operator/json || {\n echo "WARNING: Could not reach PyPI. Network connectivity issues might prevent installation."\n }\nfi\n\necho "Installing local-operator package..."\npython -m pip install --verbose local-operator || {\n echo "ERROR: Failed to install local-operator package. Exit code: $?"\n echo "Python version:"\n python --version\n echo "pip version:"\n pip --version\n echo "Available pip packages:"\n pip list\n exit 1\n}\necho "local-operator installation successful"\n\n# Verify installation\nif [ -f "$VENV_PATH/bin/local-operator" ]; then\n log "Local Operator backend installed successfully!"\n \n # Show more information about the installed binary\n ls -la "$VENV_PATH/bin/local-operator" || true\n file "$VENV_PATH/bin/local-operator" 2>/dev/null || log "Note: \'file\' command not available"\n \n # Try to run the version command with full error output\n log "Testing local-operator binary..."\n "$VENV_PATH/bin/local-operator" --version || {\n log "ERROR: local-operator binary exists but failed to execute. Exit code: $?"\n log "Binary details:"\n file "$VENV_PATH/bin/local-operator" 2>/dev/null || log "Note: \'file\' command not available"\n log "Binary permissions:"\n ls -la "$VENV_PATH/bin/local-operator" || true\n log ""\n log "This could be due to missing dependencies or architecture incompatibility."\n log "Try running the binary manually to see specific errors."\n \n # Don\'t exit here - just warn the user\n log "WARNING: Installation completed but binary verification failed."\n }\n \n # Create a summary of the installation\n SUMMARY_FILE="${APP_DATA_DIR}/installation-summary-${TIMESTAMP}.txt"\n {\n echo "=== Local Operator Backend Installation Summary ==="\n echo "Timestamp: $(date)"\n echo "Python Version: $("${PYTHON_BIN}" --version 2>&1)"\n echo "Virtual Environment: ${VENV_PATH}"\n echo "Binary Location: ${VENV_PATH}/bin/local-operator"\n echo "To activate the virtual environment, run: source ${VENV_PATH}/bin/activate"\n echo "To test the installation, run: ${VENV_PATH}/bin/local-operator --version"\n echo "Log file: ${LOG_FILE}"\n echo "=================================================="\n } > "${SUMMARY_FILE}"\n \n log "Installation summary saved to: ${SUMMARY_FILE}"\nelse\n log "Error: Failed to install Local Operator backend. Binary not found."\n log "Contents of bin directory:"\n ls -la "$VENV_PATH/bin/" || true\n log "Check the log file for details: ${LOG_FILE}"\n error_exit "Installation failed. Binary not installed properly."\nfi\n\nlog "Installation completed successfully at $(date)"\n\n# Clean up temporary files now that installation is complete\ncleanup\n\n# Print final instructions\nlog ""\nlog "=== INSTALLATION COMPLETE ==="\nlog "You can now use the Local Operator backend by running: ${VENV_PATH}/bin/local-operator"\nlog "Installation directory: ${VENV_PATH}"\nlog "Log file: ${LOG_FILE}"\nlog "================================"\n';
|
|
2857
|
+
const linuxInstallScriptRaw = '#!/bin/bash\n# Local Operator Backend Installation Script for Linux\n# This script sets up a virtual environment for the Local Operator backend\n# without requiring sudo or admin privileges.\n\n# Exit on error, undefined variables, and failed pipe commands\nset -e # Exit immediately if a command exits with a non-zero status\nset -u # Error on unset variables\nset -o pipefail # Fail if any command in a pipe fails\n\n# Configuration\n# Variables APP_NAME and MIN_PYTHON_VERSION removed as they were unused\nVENV_NAME="local-operator-venv"\nAPP_DATA_DIR="${HOME}/.config/local-operator"\nVENV_PATH="${APP_DATA_DIR}/${VENV_NAME}"\nLOG_FILE="${APP_DATA_DIR}/backend-install.log"\nTIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")\n\n# Keep CPython\'s bytecode cache out of the application directory.\n#\n# Same reason as the macOS script: an interpreter writing __pycache__/*.pyc\n# beside its own stdlib sources writes into the installed tree. Linux does not\n# code-seal the app the way macOS does, so this is uniformity and hygiene here\n# rather than the load-bearing fix it is on macOS - but it is also the value a\n# standalone run of this script has to agree with, because the app and the\n# script must not disagree about where bytecode goes.\n: "${PYTHONPYCACHEPREFIX:=${APP_DATA_DIR}/python-bytecode-cache}"\nexport PYTHONPYCACHEPREFIX\n\n# Create app data directory if it doesn\'t exist\nif ! mkdir -p "${APP_DATA_DIR}"; then\n echo "ERROR: Unable to create app data directory at ${APP_DATA_DIR}"\n echo "Please check permissions and try again."\n exit 1\nfi\n\n# Handle cleanup on script exit\ncleanup() {\n # Remove any temporary files created during execution\n if [ -f "${APP_DATA_DIR}/get-pip.py" ]; then\n rm -f "${APP_DATA_DIR}/get-pip.py"\n fi\n if [ -n "${FFMPEG_TEMP_ARCHIVE:-}" ] && [ -f "${FFMPEG_TEMP_ARCHIVE}" ]; then\n log "Removing temporary FFmpeg archive: ${FFMPEG_TEMP_ARCHIVE}"\n rm -f "${FFMPEG_TEMP_ARCHIVE}"\n fi\n echo "$(date): Cleanup completed."\n}\n\n# Set trap only for manual interruption (SIGINT, SIGTERM), not normal exits\ntrap cleanup SIGINT SIGTERM\n\n\n# Start logging\nexec > >(tee -a "${LOG_FILE}") 2>&1\necho "[${TIMESTAMP}]: Starting Local Operator backend installation..."\necho "[${TIMESTAMP}]: System information: $(uname -a)"\n\n# Function to log messages with timestamp (defined later, but used by FFmpeg section)\n_log_internal() {\n local internal_timestamp\n internal_timestamp=$(date +"%Y-%m-%d %H:%M:%S")\n echo "[${internal_timestamp}] $1"\n}\n\n# --- FFmpeg Installation ---\nBIN_DIR="${APP_DATA_DIR}/bin"\nFFMPEG_BIN="${BIN_DIR}/ffmpeg" # Path to ffmpeg binary\n\n_log_internal "Ensuring bin directory exists: ${BIN_DIR}"\nif ! mkdir -p "${BIN_DIR}"; then\n _log_internal "ERROR: Unable to create bin directory at ${BIN_DIR}"\n exit 1\nfi\n\n# Check if FFmpeg is already installed and executable\nif [ -f "${FFMPEG_BIN}" ] && [ -x "${FFMPEG_BIN}" ]; then\n _log_internal "FFmpeg already installed at ${FFMPEG_BIN}. Skipping download."\nelse\n _log_internal "FFmpeg not found or not executable. Attempting to download and install FFmpeg..."\n\n FFMPEG_DOWNLOAD_URL=""\n\n LINUX_ARCH=$(uname -m)\n if [[ "${LINUX_ARCH}" == "x86_64" ]]; then\n FFMPEG_DOWNLOAD_URL="https://github.com/eugeneware/ffmpeg-static/releases/download/b6.0/ffmpeg-linux-x64"\n elif [[ "${LINUX_ARCH}" == "aarch64" ]] || [[ "${LINUX_ARCH}" == "arm64" ]]; then\n FFMPEG_DOWNLOAD_URL="https://github.com/eugeneware/ffmpeg-static/releases/download/b6.0/ffmpeg-linux-arm64"\n else\n _log_internal "Error: Unsupported CPU architecture for FFmpeg download: ${LINUX_ARCH}"\n exit 1\n fi\n\n _log_internal "Downloading FFmpeg from: ${FFMPEG_DOWNLOAD_URL}"\n if command -v curl >/dev/null 2>&1; then\n if ! curl -L "${FFMPEG_DOWNLOAD_URL}" -o "${FFMPEG_BIN}"; then\n _log_internal "Error: Failed to download FFmpeg using curl from ${FFMPEG_DOWNLOAD_URL}"\n exit 1\n fi\n elif command -v wget >/dev/null 2>&1; then\n if ! wget -O "${FFMPEG_BIN}" "${FFMPEG_DOWNLOAD_URL}"; then\n _log_internal "Error: Failed to download FFmpeg using wget from ${FFMPEG_DOWNLOAD_URL}"\n exit 1\n fi\n else\n _log_internal "Error: Neither curl nor wget found. Cannot download FFmpeg."\n exit 1\n fi\n _log_internal "FFmpeg binary downloaded successfully to ${FFMPEG_BIN}"\n\n chmod +x "${FFMPEG_BIN}"\n _log_internal "Set executable permissions for ${FFMPEG_BIN}"\n\n # Verify FFmpeg is executable after download\n if [ ! -f "${FFMPEG_BIN}" ] || [ ! -x "${FFMPEG_BIN}" ]; then\n _log_internal "Error: FFmpeg binary not found or not executable after download."\n exit 1\n fi\nfi\n\n_log_internal "FFmpeg installation complete. FFmpeg binary is at: ${FFMPEG_BIN}"\n\n# Function to check if a command exists\ncommand_exists() {\n command -v "$1" >/dev/null 2>&1\n}\n\n# Function to log messages with timestamp\nlog() {\n local timestamp\n timestamp=$(date +"%Y-%m-%d %H:%M:%S")\n echo "[${timestamp}] $1"\n}\n\n# Function to display error messages and exit\nerror_exit() {\n log "ERROR: $1" >&2\n exit "${2:-1}"\n}\n\n# Function to check if Python binary is valid for current architecture\nis_valid_python_binary() {\n local python_path="$1"\n \n # First check if file exists and is executable\n if [ ! -f "${python_path}" ] || [ ! -x "${python_path}" ]; then\n return 1\n fi\n \n # Try to run a simple Python command to verify it works on current architecture\n "${python_path}" -c "print(\'Testing Python executable\')" >/dev/null 2>&1\n return $?\n}\n\n# Check for network connectivity to key servers\ncheck_connectivity() {\n log "Checking network connectivity..."\n local servers=("pypi.org" "bootstrap.pypa.io")\n local has_connectivity=false\n \n for server in "${servers[@]}"; do\n if command_exists curl; then\n if curl --connect-timeout 5 -s "https://${server}" -o /dev/null; then\n has_connectivity=true\n break\n fi\n elif command_exists wget; then\n if wget --timeout=5 -q --spider "https://${server}"; then\n has_connectivity=true\n break\n fi\n fi\n done\n \n if [ "$has_connectivity" = false ]; then\n log "WARNING: Network connectivity issues detected. This may affect installation."\n else\n log "Network connectivity confirmed."\n fi\n}\n\n# Call connectivity check\ncheck_connectivity\n\n# Check if PYTHON_BIN is already set by the installer\nif [ -n "${PYTHON_BIN:-}" ]; then\n log "Using Python executable provided by installer: ${PYTHON_BIN}"\n # Verify the provided Python binary works on this architecture\n if ! is_valid_python_binary "${PYTHON_BIN}"; then\n log "Warning: The provided Python binary is not compatible with this system architecture."\n log "Will attempt to find a system Python installation instead."\n PYTHON_BIN=""\n fi\nfi\n\n# If PYTHON_BIN is empty or invalid, try to find a suitable Python installation\nif [ -z "${PYTHON_BIN:-}" ] || ! is_valid_python_binary "${PYTHON_BIN:-}"; then\n # Try to find a suitable Python installation\n log "Looking for a suitable Python installation..."\n \n # Try multiple possible locations to find Python\n POSSIBLE_PYTHON_PATHS=(\n # System paths first (more likely to be compatible with current architecture)\n "/usr/local/bin/python3.12"\n "/usr/bin/python3.12"\n "/usr/local/bin/python3"\n "/usr/bin/python3"\n # From environment variable (set by the installer)\n "${ELECTRON_RESOURCE_PATH:-}/python/bin/python3"\n # Development paths\n "$(dirname "$0")/../../../resources/python/bin/python3"\n "$(pwd)/resources/python/bin/python3"\n )\n\n # Find the first Python that exists and is version 3.12+ and works on this architecture\n PYTHON_BIN=""\n for path in "${POSSIBLE_PYTHON_PATHS[@]}"; do\n # Skip empty paths that might come from unset environment variables\n if [ -z "${path}" ]; then\n continue\n fi\n \n if is_valid_python_binary "${path}"; then\n # Check Python version\n if PY_VERSION=$("${path}" -c "import sys; print(f\'{sys.version_info.major}.{sys.version_info.minor}\')" 2>/dev/null); then\n MAJOR=$(echo "${PY_VERSION}" | cut -d. -f1)\n MINOR=$(echo "${PY_VERSION}" | cut -d. -f2)\n if [ "${MAJOR}" -eq 3 ] && [ "${MINOR}" -ge 12 ]; then\n PYTHON_BIN="${path}"\n log "Found suitable Python ${PY_VERSION} at ${path}"\n break\n else\n log "Python at ${path} is version ${PY_VERSION}, which is below the required 3.12+"\n fi\n fi\n else\n if [ -f "${path}" ]; then\n log "Python at ${path} exists but is not compatible with this system architecture"\n fi\n fi\n done\n\n # If we couldn\'t find a suitable Python, exit with error\n if [ -z "${PYTHON_BIN:-}" ]; then\n error_exit "No suitable Python installation found (version 3.12 or higher required).\\nPlease install Python 3.12 or higher before running this script.\\nYou can install Python from https://www.python.org/downloads/"\n fi\nfi\n\necho "Using Python: $PYTHON_BIN"\n"$PYTHON_BIN" --version || {\n echo "Error: Failed to run Python. Please ensure it is executable and accessible."\n echo "System architecture: $(uname -m)"\n echo "Python binary architecture: $(file "$PYTHON_BIN" 2>/dev/null || echo \'Unable to determine\')"\n exit 1\n}\n\n# Detect the Linux distribution to provide specific instructions\nif command_exists lsb_release; then\n DISTRO=$(lsb_release -is)\n DISTRO_VERSION=$(lsb_release -rs)\n echo "Detected Linux distribution: $DISTRO $DISTRO_VERSION"\nelif [ -f /etc/os-release ]; then\n DISTRO=$(grep -oP \'(?<=^ID=).+\' /etc/os-release | tr -d \'"\')\n DISTRO_VERSION=$(grep -oP \'(?<=^VERSION_ID=).+\' /etc/os-release | tr -d \'"\')\n echo "Detected Linux distribution: $DISTRO $DISTRO_VERSION"\nelse\n DISTRO="unknown"\n echo "Unable to detect Linux distribution"\nfi\n\n# Check if Python has venv module and ensurepip available\nlog "Checking for venv module and ensurepip availability..."\nVENV_AVAILABLE=0\nENSUREPIP_AVAILABLE=0\n\n"${PYTHON_BIN}" -c "import venv" > /dev/null 2>&1 || VENV_AVAILABLE=1\n"${PYTHON_BIN}" -c "import ensurepip" > /dev/null 2>&1 || ENSUREPIP_AVAILABLE=1\n\n# If venv is still not available, try to use virtualenv as a fallback\nif [ $VENV_AVAILABLE -ne 0 ]; then\n echo "venv module is not available. Checking for virtualenv as an alternative..."\n \n # Check if virtualenv is already installed\n if "$PYTHON_BIN" -c "import virtualenv" > /dev/null 2>&1; then\n echo "virtualenv is available, will use it instead of venv"\n else\n echo "ERROR: Neither venv nor virtualenv is available."\n echo "Python 3.12 and venv should be installed as package dependencies."\n echo "Please ensure Python 3.12 and venv are properly installed on your system."\n exit 1\n fi\nfi\n\n# Create virtual environment if it doesn\'t exist\nif [ ! -d "$VENV_PATH" ]; then\n echo "Creating virtual environment at $VENV_PATH..."\n # Remove any potentially corrupted virtual environment\n if [ -e "$VENV_PATH" ]; then\n echo "Removing existing but potentially corrupted venv directory..."\n rm -rf "$VENV_PATH"\n fi\n \n # Make sure parent directory exists and is writable\n mkdir -p "$(dirname "$VENV_PATH")"\n \n # Try different methods to create a virtual environment\n VENV_CREATE_STATUS=1\n \n # First try with venv if available\n if [ $VENV_AVAILABLE -eq 0 ] && [ $ENSUREPIP_AVAILABLE -eq 0 ]; then\n echo "Creating virtual environment using venv module..."\n "$PYTHON_BIN" -m venv "$VENV_PATH"\n VENV_CREATE_STATUS=$?\n fi\n \n # If venv failed, try virtualenv\n if [ $VENV_CREATE_STATUS -ne 0 ]; then\n echo "venv creation failed with status $VENV_CREATE_STATUS. Falling back to virtualenv..."\n if command_exists virtualenv; then\n virtualenv -p "$PYTHON_BIN" "$VENV_PATH"\n VENV_CREATE_STATUS=$?\n elif "$PYTHON_BIN" -m pip list | grep -q virtualenv; then\n "$PYTHON_BIN" -m virtualenv -p "$PYTHON_BIN" "$VENV_PATH"\n VENV_CREATE_STATUS=$?\n else\n echo "ERROR: Both venv and virtualenv are unavailable or failed."\n echo "Python 3.12 and venv should be installed as package dependencies."\n echo "Please ensure Python 3.12 and venv are properly installed on your system."\n echo "You can install Python 3.12 from https://www.python.org/downloads/"\n exit 1\n fi\n fi\n \n # Check if virtual environment creation was successful\n if [ $VENV_CREATE_STATUS -ne 0 ]; then\n log "ERROR: Failed to create virtual environment. Exit code: $VENV_CREATE_STATUS"\n log "Virtual environment path: $VENV_PATH"\n log "Python binary used: $PYTHON_BIN"\n ls -la "$(dirname "$VENV_PATH")" || true\n log "Python executable permissions:"\n ls -la "$PYTHON_BIN" || true\n \n # Check for common issues\n log "Checking for common virtual environment creation issues..."\n \n # Check disk space\n df -h "$(dirname "$VENV_PATH")" || true\n \n # Check if directory is writable\n if [ ! -w "$(dirname "$VENV_PATH")" ]; then\n log "ERROR: Directory $(dirname "$VENV_PATH") is not writable"\n fi\n \n # Try to create a minimal virtual environment manually as a last resort\n log "Attempting to create a minimal virtual environment manually..."\n mkdir -p "$VENV_PATH/bin" || error_exit "Could not create directory $VENV_PATH/bin"\n echo "#!/bin/bash" > "$VENV_PATH/bin/activate"\n echo "export VIRTUAL_ENV=\\"$VENV_PATH\\"" >> "$VENV_PATH/bin/activate"\n echo "export PATH=\\"$VENV_PATH/bin:\\$PATH\\"" >> "$VENV_PATH/bin/activate"\n echo "unset PYTHONHOME" >> "$VENV_PATH/bin/activate"\n chmod +x "$VENV_PATH/bin/activate" || error_exit "Could not set execute permissions on activate script"\n \n # Create symlinks to the system Python\n ln -sf "$PYTHON_BIN" "$VENV_PATH/bin/python" || log "WARNING: Failed to create symlink for python"\n ln -sf "$PYTHON_BIN" "$VENV_PATH/bin/python3" || log "WARNING: Failed to create symlink for python3"\n \n # Try to bootstrap pip\n log "Bootstrapping pip in the minimal virtual environment..."\n if command_exists curl; then\n curl -s https://bootstrap.pypa.io/get-pip.py -o "$APP_DATA_DIR/get-pip.py" || log "WARNING: Failed to download get-pip.py"\n elif command_exists wget; then\n wget -q -O "$APP_DATA_DIR/get-pip.py" https://bootstrap.pypa.io/get-pip.py || log "WARNING: Failed to download get-pip.py"\n else\n log "ERROR: Neither curl nor wget available to download get-pip.py"\n error_exit "Installation cannot continue without being able to download pip"\n fi\n \n # shellcheck disable=SC1090\n source "$VENV_PATH/bin/activate" && python "$APP_DATA_DIR/get-pip.py" --no-warn-script-location\n \n if [ ! -f "$VENV_PATH/bin/pip" ]; then\n error_exit "Failed to create even a minimal virtual environment."\n else\n log "Created a minimal virtual environment as a fallback."\n fi\n else\n log "Successfully created virtual environment"\n fi\nfi\n\n# Verify the virtual environment structure\necho "Verifying virtual environment structure..."\nif [ ! -f "$VENV_PATH/bin/python" ]; then\n echo "Python executable missing in virtual environment, creating symlink..."\n ln -sf "$PYTHON_BIN" "$VENV_PATH/bin/python"\nfi\n\nif [ ! -f "$VENV_PATH/bin/pip" ]; then\n echo "pip missing in virtual environment, attempting to bootstrap it..."\n curl -s https://bootstrap.pypa.io/get-pip.py -o "$APP_DATA_DIR/get-pip.py"\n "$VENV_PATH/bin/python" "$APP_DATA_DIR/get-pip.py" --no-warn-script-location\n \n if [ ! -f "$VENV_PATH/bin/pip" ]; then\n echo "ERROR: Failed to bootstrap pip in the virtual environment"\n exit 1\n fi\nfi\n\necho "Virtual environment structure verified"\n\n# Activate virtual environment and install local-operator\necho "Installing local-operator in virtual environment..."\nsource "$VENV_PATH/bin/activate"\n\necho "Upgrading pip..."\npython -m pip install --upgrade pip || {\n echo "WARNING: Failed to upgrade pip. Will try to continue with existing pip version."\n pip --version\n}\n\n# Check network connectivity to PyPI\necho "Checking network connectivity to PyPI..."\nif command_exists curl; then\n curl -s https://pypi.org/pypi/local-operator/json -o /dev/null || {\n echo "WARNING: Could not reach PyPI. Network connectivity issues might prevent installation."\n }\nelif command_exists wget; then\n wget -q --spider https://pypi.org/pypi/local-operator/json || {\n echo "WARNING: Could not reach PyPI. Network connectivity issues might prevent installation."\n }\nfi\n\necho "Installing local-operator package..."\npython -m pip install --verbose local-operator || {\n echo "ERROR: Failed to install local-operator package. Exit code: $?"\n echo "Python version:"\n python --version\n echo "pip version:"\n pip --version\n echo "Available pip packages:"\n pip list\n exit 1\n}\necho "local-operator installation successful"\n\n# Verify installation\nif [ -f "$VENV_PATH/bin/local-operator" ]; then\n log "Local Operator backend installed successfully!"\n \n # Show more information about the installed binary\n ls -la "$VENV_PATH/bin/local-operator" || true\n file "$VENV_PATH/bin/local-operator" 2>/dev/null || log "Note: \'file\' command not available"\n \n # Try to run the version command with full error output\n log "Testing local-operator binary..."\n "$VENV_PATH/bin/local-operator" --version || {\n log "ERROR: local-operator binary exists but failed to execute. Exit code: $?"\n log "Binary details:"\n file "$VENV_PATH/bin/local-operator" 2>/dev/null || log "Note: \'file\' command not available"\n log "Binary permissions:"\n ls -la "$VENV_PATH/bin/local-operator" || true\n log ""\n log "This could be due to missing dependencies or architecture incompatibility."\n log "Try running the binary manually to see specific errors."\n \n # Don\'t exit here - just warn the user\n log "WARNING: Installation completed but binary verification failed."\n }\n \n # Create a summary of the installation\n SUMMARY_FILE="${APP_DATA_DIR}/installation-summary-${TIMESTAMP}.txt"\n {\n echo "=== Local Operator Backend Installation Summary ==="\n echo "Timestamp: $(date)"\n echo "Python Version: $("${PYTHON_BIN}" --version 2>&1)"\n echo "Virtual Environment: ${VENV_PATH}"\n echo "Binary Location: ${VENV_PATH}/bin/local-operator"\n echo "To activate the virtual environment, run: source ${VENV_PATH}/bin/activate"\n echo "To test the installation, run: ${VENV_PATH}/bin/local-operator --version"\n echo "Log file: ${LOG_FILE}"\n echo "=================================================="\n } > "${SUMMARY_FILE}"\n \n log "Installation summary saved to: ${SUMMARY_FILE}"\nelse\n log "Error: Failed to install Local Operator backend. Binary not found."\n log "Contents of bin directory:"\n ls -la "$VENV_PATH/bin/" || true\n log "Check the log file for details: ${LOG_FILE}"\n error_exit "Installation failed. Binary not installed properly."\nfi\n\nlog "Installation completed successfully at $(date)"\n\n# Clean up temporary files now that installation is complete\ncleanup\n\n# Print final instructions\nlog ""\nlog "=== INSTALLATION COMPLETE ==="\nlog "You can now use the Local Operator backend by running: ${VENV_PATH}/bin/local-operator"\nlog "Installation directory: ${VENV_PATH}"\nlog "Log file: ${LOG_FILE}"\nlog "================================"\n';
|
|
2822
2858
|
const macosInstallScriptRaw = `#!/bin/bash
|
|
2823
2859
|
# Local Operator Backend Installation Script for macOS
|
|
2824
2860
|
# This script uses the bundled standalone Python and sets up a virtual environment for the Local Operator backend.
|
|
@@ -2832,6 +2868,22 @@ APP_DATA_DIR="$HOME/Library/Application Support/$APP_NAME"
|
|
|
2832
2868
|
VENV_PATH="$APP_DATA_DIR/$VENV_NAME"
|
|
2833
2869
|
LOG_FILE="$APP_DATA_DIR/backend-install.log"
|
|
2834
2870
|
|
|
2871
|
+
# Keep CPython's bytecode cache out of the application bundle.
|
|
2872
|
+
#
|
|
2873
|
+
# The bundled interpreter writes __pycache__/*.pyc beside the stdlib sources it
|
|
2874
|
+
# imports, and those sources live inside the code-signed .app - which is the
|
|
2875
|
+
# build's own extraResource. Every such write is a change to a sealed resource:
|
|
2876
|
+
# measured on an installed 0.17.3, \`codesign --verify --deep\` reported 308
|
|
2877
|
+
# \`file added:\` violations, all of them .pyc, and ShipIt then refuses the
|
|
2878
|
+
# in-place update with -67028 errSecCSBadBundleFormat. A file codesign reports
|
|
2879
|
+
# as *added* can be deleted and the seal comes back; a *modified* one cannot,
|
|
2880
|
+
# which is why nothing may ship a .pyc at all. The app sets this variable when
|
|
2881
|
+
# it spawns us; defaulting it here means a standalone run of this script cannot
|
|
2882
|
+
# pollute the bundle either. $HOME is the right place for the same reason the
|
|
2883
|
+
# venv lives there: it is never inside the thing that gets signed and swapped.
|
|
2884
|
+
: "\${PYTHONPYCACHEPREFIX:=$APP_DATA_DIR/python-bytecode-cache}"
|
|
2885
|
+
export PYTHONPYCACHEPREFIX
|
|
2886
|
+
|
|
2835
2887
|
# Determine CPU Architecture and Python Directory Name
|
|
2836
2888
|
ARCH=$(uname -m)
|
|
2837
2889
|
PYTHON_DIR_NAME="python" # Default for x86_64
|
|
@@ -3102,6 +3154,19 @@ $VenvPath = "$AppDataDir\\\\$VenvName"
|
|
|
3102
3154
|
$LogFile = "$AppDataDir\\\\backend-install-shell.log"
|
|
3103
3155
|
$PyenvDir = "$env:USERPROFILE\\\\.pyenv"
|
|
3104
3156
|
|
|
3157
|
+
# Keep CPython's bytecode cache out of the application directory.
|
|
3158
|
+
#
|
|
3159
|
+
# Same rule as the macOS script, and stated here for the same reason: an
|
|
3160
|
+
# interpreter writes __pycache__/*.pyc beside the stdlib sources it imports. On
|
|
3161
|
+
# Windows those sources are the bundled python directory rather than a
|
|
3162
|
+
# code-signed bundle, so this is hygiene rather than the load-bearing fix it is
|
|
3163
|
+
# on macOS - but the app and the script must not disagree about where bytecode
|
|
3164
|
+
# goes. $AppDataDir is used for the same reason the venv is: it is never inside
|
|
3165
|
+
# the installed application tree.
|
|
3166
|
+
if (-not $env:PYTHONPYCACHEPREFIX) {
|
|
3167
|
+
$env:PYTHONPYCACHEPREFIX = "$AppDataDir\\\\python-bytecode-cache"
|
|
3168
|
+
}
|
|
3169
|
+
|
|
3105
3170
|
# Create app data directory if it doesn't exist
|
|
3106
3171
|
if (-not (Test-Path $AppDataDir)) {
|
|
3107
3172
|
New-Item -ItemType Directory -Path $AppDataDir -Force | Out-Null
|
|
@@ -3672,7 +3737,7 @@ class BackendInstaller {
|
|
|
3672
3737
|
electron.app.once("before-quit", appQuitHandler);
|
|
3673
3738
|
const result = await new Promise((resolve) => {
|
|
3674
3739
|
try {
|
|
3675
|
-
const env = { ...process.env };
|
|
3740
|
+
const env = withPythonBytecodeCache({ ...process.env }, this.appDataPath);
|
|
3676
3741
|
env.ELECTRON_RESOURCE_PATH = this.resourcesPath;
|
|
3677
3742
|
logger.info(
|
|
3678
3743
|
`Setting ELECTRON_RESOURCE_PATH to ${this.resourcesPath}`,
|
|
@@ -4472,6 +4537,111 @@ function installedBundleSealBlock(appBundlePath, detail, version2) {
|
|
|
4472
4537
|
detail: `${appBundlePath}: ${detail}`
|
|
4473
4538
|
};
|
|
4474
4539
|
}
|
|
4540
|
+
const VIOLATION_LINE = /^file (added|modified|missing):\s*(.+)$/;
|
|
4541
|
+
function parseSealViolations(output) {
|
|
4542
|
+
const violations = [];
|
|
4543
|
+
for (const rawLine of output.split("\n")) {
|
|
4544
|
+
const line = rawLine.trim();
|
|
4545
|
+
if (line.length === 0) continue;
|
|
4546
|
+
const match = VIOLATION_LINE.exec(line);
|
|
4547
|
+
if (match) {
|
|
4548
|
+
violations.push({
|
|
4549
|
+
kind: match[1],
|
|
4550
|
+
path: match[2].trim()
|
|
4551
|
+
});
|
|
4552
|
+
continue;
|
|
4553
|
+
}
|
|
4554
|
+
violations.push({ kind: "other", path: line });
|
|
4555
|
+
}
|
|
4556
|
+
return violations;
|
|
4557
|
+
}
|
|
4558
|
+
function canonicalPath(path$1) {
|
|
4559
|
+
try {
|
|
4560
|
+
return fs.realpathSync(path$1);
|
|
4561
|
+
} catch {
|
|
4562
|
+
try {
|
|
4563
|
+
return path.join(fs.realpathSync(path.dirname(path$1)), path.basename(path$1));
|
|
4564
|
+
} catch {
|
|
4565
|
+
return path$1;
|
|
4566
|
+
}
|
|
4567
|
+
}
|
|
4568
|
+
}
|
|
4569
|
+
const BUNDLED_PYTHON_DIRS = ["python", "python_aarch64"];
|
|
4570
|
+
function isPythonBytecodePath(bundlePath, candidate) {
|
|
4571
|
+
const bundle = canonicalPath(bundlePath);
|
|
4572
|
+
const path$1 = canonicalPath(candidate);
|
|
4573
|
+
const dirs = BUNDLED_PYTHON_DIRS.map(
|
|
4574
|
+
(name) => path.join(bundle, "Contents", "Resources", name)
|
|
4575
|
+
);
|
|
4576
|
+
const separator = "/";
|
|
4577
|
+
if (!path$1.endsWith(".pyc")) return false;
|
|
4578
|
+
const segments = path$1.split(separator);
|
|
4579
|
+
if (!segments.includes("__pycache__")) return false;
|
|
4580
|
+
return dirs.some((dir) => path$1.startsWith(`${dir}${separator}`));
|
|
4581
|
+
}
|
|
4582
|
+
function planPythonBytecodeHeal(bundlePath, violations) {
|
|
4583
|
+
const added = violations.filter((violation) => violation.kind === "added");
|
|
4584
|
+
const elsewhere = violations.filter(
|
|
4585
|
+
(violation) => violation.kind !== "added"
|
|
4586
|
+
);
|
|
4587
|
+
if (added.length === 0) {
|
|
4588
|
+
return {
|
|
4589
|
+
healable: false,
|
|
4590
|
+
reason: `no added-resource violation to heal (${violations.length} violation(s))`,
|
|
4591
|
+
paths: []
|
|
4592
|
+
};
|
|
4593
|
+
}
|
|
4594
|
+
if (elsewhere.length > 0) {
|
|
4595
|
+
const kinds = [...new Set(elsewhere.map((violation) => violation.kind))];
|
|
4596
|
+
return {
|
|
4597
|
+
healable: false,
|
|
4598
|
+
reason: `unhealable violation class(es) present: ${kinds.join(", ")}`,
|
|
4599
|
+
paths: []
|
|
4600
|
+
};
|
|
4601
|
+
}
|
|
4602
|
+
const outside = added.filter(
|
|
4603
|
+
(violation) => !isPythonBytecodePath(bundlePath, violation.path)
|
|
4604
|
+
);
|
|
4605
|
+
if (outside.length > 0) {
|
|
4606
|
+
return {
|
|
4607
|
+
healable: false,
|
|
4608
|
+
reason: `added resource outside the bundled python trees: ${outside[0].path}`,
|
|
4609
|
+
paths: []
|
|
4610
|
+
};
|
|
4611
|
+
}
|
|
4612
|
+
return {
|
|
4613
|
+
healable: true,
|
|
4614
|
+
reason: `${added.length} bytecode file(s) added after signing`,
|
|
4615
|
+
paths: [...new Set(added.map((violation) => violation.path))]
|
|
4616
|
+
};
|
|
4617
|
+
}
|
|
4618
|
+
function healPythonBytecode(bundlePath, violations, remove = (path2) => fs.rmSync(path2, { force: true })) {
|
|
4619
|
+
const plan = planPythonBytecodeHeal(bundlePath, violations);
|
|
4620
|
+
if (!plan.healable) return { ...plan, removed: [] };
|
|
4621
|
+
const removed = [];
|
|
4622
|
+
for (const path2 of plan.paths) {
|
|
4623
|
+
if (!isPythonBytecodePath(bundlePath, path2)) {
|
|
4624
|
+
return {
|
|
4625
|
+
healable: false,
|
|
4626
|
+
reason: `refused to remove ${path2}: not bytecode under the bundled python trees`,
|
|
4627
|
+
paths: plan.paths,
|
|
4628
|
+
removed
|
|
4629
|
+
};
|
|
4630
|
+
}
|
|
4631
|
+
try {
|
|
4632
|
+
remove(path2);
|
|
4633
|
+
removed.push(path2);
|
|
4634
|
+
} catch (error) {
|
|
4635
|
+
return {
|
|
4636
|
+
healable: false,
|
|
4637
|
+
reason: `could not remove ${path2}: ${error instanceof Error ? error.message : String(error)}`,
|
|
4638
|
+
paths: plan.paths,
|
|
4639
|
+
removed
|
|
4640
|
+
};
|
|
4641
|
+
}
|
|
4642
|
+
}
|
|
4643
|
+
return { ...plan, removed };
|
|
4644
|
+
}
|
|
4475
4645
|
function metadataBasenames(filePath, updatePath) {
|
|
4476
4646
|
const names = [path.basename(filePath)];
|
|
4477
4647
|
if (updatePath) names.push(path.basename(updatePath));
|
|
@@ -5318,7 +5488,11 @@ function runCommand(command, args, options = {}) {
|
|
|
5318
5488
|
node_child_process.execFile(
|
|
5319
5489
|
command,
|
|
5320
5490
|
args,
|
|
5321
|
-
{
|
|
5491
|
+
{
|
|
5492
|
+
timeout: options.timeoutMs ?? 2e4,
|
|
5493
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
5494
|
+
...options.env ? { env: options.env } : {}
|
|
5495
|
+
},
|
|
5322
5496
|
(error, stdout, stderr) => {
|
|
5323
5497
|
const code = error?.code;
|
|
5324
5498
|
const killed = error?.killed === true;
|
|
@@ -5457,6 +5631,20 @@ class UpdateService {
|
|
|
5457
5631
|
markerDir() {
|
|
5458
5632
|
return electron.app.getPath("userData");
|
|
5459
5633
|
}
|
|
5634
|
+
/**
|
|
5635
|
+
* The environment every python this service spawns has to run under.
|
|
5636
|
+
*
|
|
5637
|
+
* The bundled venv's `python` is the interpreter we ship, so its stdlib - and
|
|
5638
|
+
* therefore any `__pycache__` CPython writes for it - is inside the code-sealed
|
|
5639
|
+
* `.app`. `pip show` and the pip upgrade both compile stdlib modules, so both
|
|
5640
|
+
* would unseal the bundle the pre-flight is about to ask ShipIt to replace.
|
|
5641
|
+
*
|
|
5642
|
+
* userData is the location for the same reason the pending marker uses it: it
|
|
5643
|
+
* is never inside the bundle being swapped.
|
|
5644
|
+
*/
|
|
5645
|
+
pythonSpawnEnv() {
|
|
5646
|
+
return withPythonBytecodeCache(process.env, this.markerDir());
|
|
5647
|
+
}
|
|
5460
5648
|
sendToRenderer(channel, payload) {
|
|
5461
5649
|
const webContents = this.mainWindow?.webContents;
|
|
5462
5650
|
if (!webContents || webContents.isDestroyed()) return false;
|
|
@@ -5721,6 +5909,13 @@ class UpdateService {
|
|
|
5721
5909
|
* - A probe that could not run is retried once and then *allowed to proceed*.
|
|
5722
5910
|
* "We could not ask" is not "the bundle is bad", and treating it as one is
|
|
5723
5911
|
* how a transient hiccup became a permanent reinstall message (R5).
|
|
5912
|
+
*
|
|
5913
|
+
* A bundle that fails the check is given one chance to heal itself, because
|
|
5914
|
+
* the failure every 0.17.x/0.18.0 install has is ours rather than the user's:
|
|
5915
|
+
* a CPython stdlib bytecode cache written into the sealed bundle by our own
|
|
5916
|
+
* backend. Those writes are `file added:` violations and deleting exactly
|
|
5917
|
+
* those files restores the seal (measured; see `healPythonBytecode`), where a
|
|
5918
|
+
* bundle broken any other way still gets the reinstall refusal below.
|
|
5724
5919
|
*/
|
|
5725
5920
|
async probeInstalledBundleSeal(version2) {
|
|
5726
5921
|
if (process.platform !== "darwin" || !electron.app.isPackaged) return null;
|
|
@@ -5737,13 +5932,15 @@ class UpdateService {
|
|
|
5737
5932
|
["--verify", "--deep", "--verbose=2", bundlePath],
|
|
5738
5933
|
{ timeoutMs: SEAL_PROBE_TIMEOUT_MS }
|
|
5739
5934
|
);
|
|
5740
|
-
let
|
|
5935
|
+
let probe = await probeBundle();
|
|
5936
|
+
let seal = evaluateBundleSeal(probe);
|
|
5741
5937
|
if (seal.kind === "unavailable") {
|
|
5742
5938
|
logger.warn(
|
|
5743
5939
|
`Seal check did not complete, retrying once: ${seal.detail}`,
|
|
5744
5940
|
LogFileType.UPDATE_SERVICE
|
|
5745
5941
|
);
|
|
5746
|
-
|
|
5942
|
+
probe = await probeBundle();
|
|
5943
|
+
seal = evaluateBundleSeal(probe);
|
|
5747
5944
|
}
|
|
5748
5945
|
if (seal.kind === "unavailable") {
|
|
5749
5946
|
logger.warn(
|
|
@@ -5763,7 +5960,33 @@ class UpdateService {
|
|
|
5763
5960
|
`Installed bundle failed its seal check: ${seal.detail}`,
|
|
5764
5961
|
LogFileType.UPDATE_SERVICE
|
|
5765
5962
|
);
|
|
5766
|
-
|
|
5963
|
+
const violations = parseSealViolations(probe.stdout);
|
|
5964
|
+
const heal = healPythonBytecode(bundlePath, violations);
|
|
5965
|
+
if (!heal.healable) {
|
|
5966
|
+
logger.warn(
|
|
5967
|
+
`Installed bundle is not healable in place: ${heal.reason}`,
|
|
5968
|
+
LogFileType.UPDATE_SERVICE
|
|
5969
|
+
);
|
|
5970
|
+
return installedBundleSealBlock(bundlePath, seal.detail, version2);
|
|
5971
|
+
}
|
|
5972
|
+
logger.info(
|
|
5973
|
+
`Removed ${heal.removed.length} bytecode file(s) our own interpreter had written into the sealed bundle: ${heal.reason}. Paths:
|
|
5974
|
+
${heal.removed.join("\n")}`,
|
|
5975
|
+
LogFileType.UPDATE_SERVICE
|
|
5976
|
+
);
|
|
5977
|
+
const healed = evaluateBundleSeal(await probeBundle());
|
|
5978
|
+
if (healed.kind === "sealed") {
|
|
5979
|
+
logger.info(
|
|
5980
|
+
`Installed bundle sealed again after removing ${heal.removed.length} added bytecode file(s); continuing with the install.`,
|
|
5981
|
+
LogFileType.UPDATE_SERVICE
|
|
5982
|
+
);
|
|
5983
|
+
return null;
|
|
5984
|
+
}
|
|
5985
|
+
logger.error(
|
|
5986
|
+
`Installed bundle still fails its seal check after healing: ${healed.detail}`,
|
|
5987
|
+
LogFileType.UPDATE_SERVICE
|
|
5988
|
+
);
|
|
5989
|
+
return installedBundleSealBlock(bundlePath, healed.detail, version2);
|
|
5767
5990
|
}
|
|
5768
5991
|
/** File names the updater's metadata knows this update by. */
|
|
5769
5992
|
stagedArtifactCandidates(info) {
|
|
@@ -6866,7 +7089,7 @@ class UpdateService {
|
|
|
6866
7089
|
const probe = await runCommand(
|
|
6867
7090
|
pythonPath,
|
|
6868
7091
|
["-m", "pip", "show", "local-operator"],
|
|
6869
|
-
{ timeoutMs: 12e4 }
|
|
7092
|
+
{ timeoutMs: 12e4, env: this.pythonSpawnEnv() }
|
|
6870
7093
|
);
|
|
6871
7094
|
if (probe.exitCode !== 0) {
|
|
6872
7095
|
logger.warn(
|
|
@@ -7030,7 +7253,8 @@ class UpdateService {
|
|
|
7030
7253
|
LogFileType.UPDATE_SERVICE
|
|
7031
7254
|
);
|
|
7032
7255
|
const pipRun = await runCommand(pip.command, pip.args, {
|
|
7033
|
-
timeoutMs: 15 * 60 * 1e3
|
|
7256
|
+
timeoutMs: 15 * 60 * 1e3,
|
|
7257
|
+
env: this.pythonSpawnEnv()
|
|
7034
7258
|
});
|
|
7035
7259
|
logger.info(
|
|
7036
7260
|
`pip stdout:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{e as o,c as b,g as v,k as O,h as P,j as p,l as w,m as A,n as x,t as c,o as N}from"./_baseUniq-
|
|
1
|
+
import{e as o,c as b,g as v,k as O,h as P,j as p,l as w,m as A,n as x,t as c,o as N}from"./_baseUniq-zF370IN-.js";import{as as g,aa as y,at as E,au as F,av as M,aw as I,ax as _,ay as $,az as B,aA as T}from"./mermaid.core-C_9cdmTh.js";var S=/\s/;function z(n){for(var r=n.length;r--&&S.test(n.charAt(r)););return r}var G=/^\s+/;function H(n){return n&&n.slice(0,z(n)+1).replace(G,"")}var m=NaN,L=/^[-+]0x[0-9a-f]+$/i,R=/^0b[01]+$/i,q=/^0o[0-7]+$/i,C=parseInt;function K(n){if(typeof n=="number")return n;if(o(n))return m;if(g(n)){var r=typeof n.valueOf=="function"?n.valueOf():n;n=g(r)?r+"":r}if(typeof n!="string")return n===0?n:+n;n=H(n);var t=R.test(n);return t||q.test(n)?C(n.slice(2),t?2:8):L.test(n)?m:+n}var W=1/0,X=17976931348623157e292;function Y(n){if(!n)return n===0?n:0;if(n=K(n),n===W||n===-1/0){var r=n<0?-1:1;return r*X}return n===n?n:0}function D(n){var r=Y(n),t=r%1;return r===r?t?r-t:r:0}function fn(n){var r=n==null?0:n.length;return r?b(n):[]}var l=Object.prototype,J=l.hasOwnProperty,dn=y(function(n,r){n=Object(n);var t=-1,e=r.length,a=e>2?r[2]:void 0;for(a&&E(r[0],r[1],a)&&(e=1);++t<e;)for(var f=r[t],i=F(f),s=-1,d=i.length;++s<d;){var u=i[s],h=n[u];(h===void 0||M(h,l[u])&&!J.call(n,u))&&(n[u]=f[u])}return n});function un(n){var r=n==null?0:n.length;return r?n[r-1]:void 0}function Q(n){return function(r,t,e){var a=Object(r);if(!I(r)){var f=v(t);r=O(r),t=function(s){return f(a[s],s,a)}}var i=n(r,t,e);return i>-1?a[f?r[i]:i]:void 0}}var U=Math.max;function Z(n,r,t){var e=n==null?0:n.length;if(!e)return-1;var a=t==null?0:D(t);return a<0&&(a=U(e+a,0)),P(n,v(r),a)}var hn=Q(Z);function V(n,r){var t=-1,e=I(n)?Array(n.length):[];return p(n,function(a,f,i){e[++t]=r(a,f,i)}),e}function gn(n,r){var t=_(n)?w:V;return t(n,v(r))}var j=Object.prototype,k=j.hasOwnProperty;function nn(n,r){return n!=null&&k.call(n,r)}function vn(n,r){return n!=null&&A(n,r,nn)}function rn(n,r){return n<r}function tn(n,r,t){for(var e=-1,a=n.length;++e<a;){var f=n[e],i=r(f);if(i!=null&&(s===void 0?i===i&&!o(i):t(i,s)))var s=i,d=f}return d}function mn(n){return n&&n.length?tn(n,$,rn):void 0}function an(n,r,t,e){if(!g(n))return n;r=x(r,n);for(var a=-1,f=r.length,i=f-1,s=n;s!=null&&++a<f;){var d=c(r[a]),u=t;if(d==="__proto__"||d==="constructor"||d==="prototype")return n;if(a!=i){var h=s[d];u=void 0,u===void 0&&(u=g(h)?h:B(r[a+1])?[]:{})}T(s,d,u),s=s[d]}return n}function on(n,r,t){for(var e=-1,a=r.length,f={};++e<a;){var i=r[e],s=N(n,i);t(s,i)&&an(f,x(i,n),s)}return f}export{rn as a,tn as b,V as c,on as d,mn as e,fn as f,hn as g,vn as h,dn as i,D as j,un as l,gn as m,Y as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{aH as S,aI as Rn,ax as T,aJ as w,aK as xn,aL as Mn,aw as sn,aM as mn,aN as un,aO as x,au as U,aP as Cn,aQ as on,aR as Fn,aS as E,aF as gn,aT as R,as as ln,aU as Dn,aV as D,aW as Gn,aX as Un,aY as _,aA as Nn,aZ as Bn,av as Kn,a_ as X,a$ as Hn,b0 as jn,az as Yn,ay as cn,aD as Zn,b1 as m}from"./mermaid.core-BpGCpBxO.js";var qn="[object Symbol]";function N(n){return typeof n=="symbol"||S(n)&&Rn(n)==qn}function dn(n,r){for(var e=-1,t=n==null?0:n.length,a=Array(t);++e<t;)a[e]=r(n[e],e,n);return a}var J=w?w.prototype:void 0,Q=J?J.toString:void 0;function pn(n){if(typeof n=="string")return n;if(T(n))return dn(n,pn)+"";if(N(n))return Q?Q.call(n):"";var r=n+"";return r=="0"&&1/n==-1/0?"-0":r}function Xn(){}function An(n,r){for(var e=-1,t=n==null?0:n.length;++e<t&&r(n[e],e,n)!==!1;);return n}function Jn(n,r,e,t){for(var a=n.length,i=e+-1;++i<a;)if(r(n[i],i,n))return i;return-1}function Qn(n){return n!==n}function Wn(n,r,e){for(var t=e-1,a=n.length;++t<a;)if(n[t]===r)return t;return-1}function zn(n,r,e){return r===r?Wn(n,r,e):Jn(n,Qn,e)}function Vn(n,r){var e=n==null?0:n.length;return!!e&&zn(n,r,0)>-1}function $(n){return sn(n)?xn(n):Mn(n)}var kn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,nr=/^\w*$/;function B(n,r){if(T(n))return!1;var e=typeof n;return e=="number"||e=="symbol"||e=="boolean"||n==null||N(n)?!0:nr.test(n)||!kn.test(n)||r!=null&&n in Object(r)}var rr=500;function er(n){var r=mn(n,function(t){return e.size===rr&&e.clear(),t}),e=r.cache;return r}var tr=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,ir=/\\(\\)?/g,ar=er(function(n){var r=[];return n.charCodeAt(0)===46&&r.push(""),n.replace(tr,function(e,t,a,i){r.push(a?i.replace(ir,"$1"):t||e)}),r});function fr(n){return n==null?"":pn(n)}function yn(n,r){return T(n)?n:B(n,r)?[n]:ar(fr(n))}function M(n){if(typeof n=="string"||N(n))return n;var r=n+"";return r=="0"&&1/n==-1/0?"-0":r}function bn(n,r){r=yn(r,n);for(var e=0,t=r.length;n!=null&&e<t;)n=n[M(r[e++])];return e&&e==t?n:void 0}function sr(n,r,e){var t=n==null?void 0:bn(n,r);return t===void 0?e:t}function K(n,r){for(var e=-1,t=r.length,a=n.length;++e<t;)n[a+e]=r[e];return n}var W=w?w.isConcatSpreadable:void 0;function ur(n){return T(n)||un(n)||!!(W&&n&&n[W])}function Ot(n,r,e,t,a){var i=-1,f=n.length;for(e||(e=ur),a||(a=[]);++i<f;){var s=n[i];e(s)?K(a,s):t||(a[a.length]=s)}return a}function or(n,r,e,t){var a=-1,i=n==null?0:n.length;for(t&&i&&(e=n[++a]);++a<i;)e=r(e,n[a],a,n);return e}function gr(n,r){return n&&x(r,$(r),n)}function lr(n,r){return n&&x(r,U(r),n)}function Tn(n,r){for(var e=-1,t=n==null?0:n.length,a=0,i=[];++e<t;){var f=n[e];r(f,e,n)&&(i[a++]=f)}return i}function hn(){return[]}var cr=Object.prototype,dr=cr.propertyIsEnumerable,z=Object.getOwnPropertySymbols,H=z?function(n){return n==null?[]:(n=Object(n),Tn(z(n),function(r){return dr.call(n,r)}))}:hn;function pr(n,r){return x(n,H(n),r)}var Ar=Object.getOwnPropertySymbols,wn=Ar?function(n){for(var r=[];n;)K(r,H(n)),n=Cn(n);return r}:hn;function yr(n,r){return x(n,wn(n),r)}function On(n,r,e){var t=r(n);return T(n)?t:K(t,e(n))}function G(n){return On(n,$,H)}function br(n){return On(n,U,wn)}var Tr=Object.prototype,hr=Tr.hasOwnProperty;function wr(n){var r=n.length,e=new n.constructor(r);return r&&typeof n[0]=="string"&&hr.call(n,"index")&&(e.index=n.index,e.input=n.input),e}function Or(n,r){var e=r?on(n.buffer):n.buffer;return new n.constructor(e,n.byteOffset,n.byteLength)}var $r=/\w*$/;function _r(n){var r=new n.constructor(n.source,$r.exec(n));return r.lastIndex=n.lastIndex,r}var V=w?w.prototype:void 0,k=V?V.valueOf:void 0;function Sr(n){return k?Object(k.call(n)):{}}var Er="[object Boolean]",Ir="[object Date]",Pr="[object Map]",vr="[object Number]",Lr="[object RegExp]",Rr="[object Set]",xr="[object String]",Mr="[object Symbol]",mr="[object ArrayBuffer]",Cr="[object DataView]",Fr="[object Float32Array]",Dr="[object Float64Array]",Gr="[object Int8Array]",Ur="[object Int16Array]",Nr="[object Int32Array]",Br="[object Uint8Array]",Kr="[object Uint8ClampedArray]",Hr="[object Uint16Array]",jr="[object Uint32Array]";function Yr(n,r,e){var t=n.constructor;switch(r){case mr:return on(n);case Er:case Ir:return new t(+n);case Cr:return Or(n,e);case Fr:case Dr:case Gr:case Ur:case Nr:case Br:case Kr:case Hr:case jr:return Fn(n,e);case Pr:return new t;case vr:case xr:return new t(n);case Lr:return _r(n);case Rr:return new t;case Mr:return Sr(n)}}var Zr="[object Map]";function qr(n){return S(n)&&E(n)==Zr}var nn=R&&R.isMap,Xr=nn?gn(nn):qr,Jr="[object Set]";function Qr(n){return S(n)&&E(n)==Jr}var rn=R&&R.isSet,Wr=rn?gn(rn):Qr,zr=1,Vr=2,kr=4,$n="[object Arguments]",ne="[object Array]",re="[object Boolean]",ee="[object Date]",te="[object Error]",_n="[object Function]",ie="[object GeneratorFunction]",ae="[object Map]",fe="[object Number]",Sn="[object Object]",se="[object RegExp]",ue="[object Set]",oe="[object String]",ge="[object Symbol]",le="[object WeakMap]",ce="[object ArrayBuffer]",de="[object DataView]",pe="[object Float32Array]",Ae="[object Float64Array]",ye="[object Int8Array]",be="[object Int16Array]",Te="[object Int32Array]",he="[object Uint8Array]",we="[object Uint8ClampedArray]",Oe="[object Uint16Array]",$e="[object Uint32Array]",g={};g[$n]=g[ne]=g[ce]=g[de]=g[re]=g[ee]=g[pe]=g[Ae]=g[ye]=g[be]=g[Te]=g[ae]=g[fe]=g[Sn]=g[se]=g[ue]=g[oe]=g[ge]=g[he]=g[we]=g[Oe]=g[$e]=!0;g[te]=g[_n]=g[le]=!1;function C(n,r,e,t,a,i){var f,s=r&zr,u=r&Vr,d=r&kr;if(f!==void 0)return f;if(!ln(n))return n;var l=T(n);if(l){if(f=wr(n),!s)return Dn(n,f)}else{var o=E(n),c=o==_n||o==ie;if(D(n))return Gn(n,s);if(o==Sn||o==$n||c&&!a){if(f=u||c?{}:Un(n),!s)return u?yr(n,lr(f,n)):pr(n,gr(f,n))}else{if(!g[o])return a?n:{};f=Yr(n,o,s)}}i||(i=new _);var h=i.get(n);if(h)return h;i.set(n,f),Wr(n)?n.forEach(function(p){f.add(C(p,r,e,p,n,i))}):Xr(n)&&n.forEach(function(p,A){f.set(A,C(p,r,e,A,n,i))});var y=d?u?br:G:u?U:$,b=l?void 0:y(n);return An(b||n,function(p,A){b&&(A=p,p=n[A]),Nn(f,A,C(p,r,e,A,n,i))}),f}var _e="__lodash_hash_undefined__";function Se(n){return this.__data__.set(n,_e),this}function Ee(n){return this.__data__.has(n)}function I(n){var r=-1,e=n==null?0:n.length;for(this.__data__=new Bn;++r<e;)this.add(n[r])}I.prototype.add=I.prototype.push=Se;I.prototype.has=Ee;function Ie(n,r){for(var e=-1,t=n==null?0:n.length;++e<t;)if(r(n[e],e,n))return!0;return!1}function En(n,r){return n.has(r)}var Pe=1,ve=2;function In(n,r,e,t,a,i){var f=e&Pe,s=n.length,u=r.length;if(s!=u&&!(f&&u>s))return!1;var d=i.get(n),l=i.get(r);if(d&&l)return d==r&&l==n;var o=-1,c=!0,h=e&ve?new I:void 0;for(i.set(n,r),i.set(r,n);++o<s;){var y=n[o],b=r[o];if(t)var p=f?t(b,y,o,r,n,i):t(y,b,o,n,r,i);if(p!==void 0){if(p)continue;c=!1;break}if(h){if(!Ie(r,function(A,O){if(!En(h,O)&&(y===A||a(y,A,e,t,i)))return h.push(O)})){c=!1;break}}else if(!(y===b||a(y,b,e,t,i))){c=!1;break}}return i.delete(n),i.delete(r),c}function Le(n){var r=-1,e=Array(n.size);return n.forEach(function(t,a){e[++r]=[a,t]}),e}function j(n){var r=-1,e=Array(n.size);return n.forEach(function(t){e[++r]=t}),e}var Re=1,xe=2,Me="[object Boolean]",me="[object Date]",Ce="[object Error]",Fe="[object Map]",De="[object Number]",Ge="[object RegExp]",Ue="[object Set]",Ne="[object String]",Be="[object Symbol]",Ke="[object ArrayBuffer]",He="[object DataView]",en=w?w.prototype:void 0,F=en?en.valueOf:void 0;function je(n,r,e,t,a,i,f){switch(e){case He:if(n.byteLength!=r.byteLength||n.byteOffset!=r.byteOffset)return!1;n=n.buffer,r=r.buffer;case Ke:return!(n.byteLength!=r.byteLength||!i(new X(n),new X(r)));case Me:case me:case De:return Kn(+n,+r);case Ce:return n.name==r.name&&n.message==r.message;case Ge:case Ne:return n==r+"";case Fe:var s=Le;case Ue:var u=tℜif(s||(s=j),n.size!=r.size&&!u)return!1;var d=f.get(n);if(d)return d==r;t|=xe,f.set(n,r);var l=In(s(n),s(r),t,a,i,f);return f.delete(n),l;case Be:if(F)return F.call(n)==F.call(r)}return!1}var Ye=1,Ze=Object.prototype,qe=Ze.hasOwnProperty;function Xe(n,r,e,t,a,i){var f=e&Ye,s=G(n),u=s.length,d=G(r),l=d.length;if(u!=l&&!f)return!1;for(var o=u;o--;){var c=s[o];if(!(f?c in r:qe.call(r,c)))return!1}var h=i.get(n),y=i.get(r);if(h&&y)return h==r&&y==n;var b=!0;i.set(n,r),i.set(r,n);for(var p=f;++o<u;){c=s[o];var A=n[c],O=r[c];if(t)var q=f?t(O,A,c,r,n,i):t(A,O,c,n,r,i);if(!(q===void 0?A===O||a(A,O,e,t,i):q)){b=!1;break}p||(p=c=="constructor")}if(b&&!p){var P=n.constructor,v=r.constructor;P!=v&&"constructor"in n&&"constructor"in r&&!(typeof P=="function"&&P instanceof P&&typeof v=="function"&&v instanceof v)&&(b=!1)}return i.delete(n),i.delete(r),b}var Je=1,tn="[object Arguments]",an="[object Array]",L="[object Object]",Qe=Object.prototype,fn=Qe.hasOwnProperty;function We(n,r,e,t,a,i){var f=T(n),s=T(r),u=f?an:E(n),d=s?an:E(r);u=u==tn?L:u,d=d==tn?L:d;var l=u==L,o=d==L,c=u==d;if(c&&D(n)){if(!D(r))return!1;f=!0,l=!1}if(c&&!l)return i||(i=new _),f||Hn(n)?In(n,r,e,t,a,i):je(n,r,u,e,t,a,i);if(!(e&Je)){var h=l&&fn.call(n,"__wrapped__"),y=o&&fn.call(r,"__wrapped__");if(h||y){var b=h?n.value():n,p=y?r.value():r;return i||(i=new _),a(b,p,e,t,i)}}return c?(i||(i=new _),Xe(n,r,e,t,a,i)):!1}function Y(n,r,e,t,a){return n===r?!0:n==null||r==null||!S(n)&&!S(r)?n!==n&&r!==r:We(n,r,e,t,Y,a)}var ze=1,Ve=2;function ke(n,r,e,t){var a=e.length,i=a;if(n==null)return!i;for(n=Object(n);a--;){var f=e[a];if(f[2]?f[1]!==n[f[0]]:!(f[0]in n))return!1}for(;++a<i;){f=e[a];var s=f[0],u=n[s],d=f[1];if(f[2]){if(u===void 0&&!(s in n))return!1}else{var l=new _,o;if(!(o===void 0?Y(d,u,ze|Ve,t,l):o))return!1}}return!0}function Pn(n){return n===n&&!ln(n)}function nt(n){for(var r=$(n),e=r.length;e--;){var t=r[e],a=n[t];r[e]=[t,a,Pn(a)]}return r}function vn(n,r){return function(e){return e==null?!1:e[n]===r&&(r!==void 0||n in Object(e))}}function rt(n){var r=nt(n);return r.length==1&&r[0][2]?vn(r[0][0],r[0][1]):function(e){return e===n||ke(e,n,r)}}function et(n,r){return n!=null&&r in Object(n)}function tt(n,r,e){r=yn(r,n);for(var t=-1,a=r.length,i=!1;++t<a;){var f=M(r[t]);if(!(i=n!=null&&e(n,f)))break;n=n[f]}return i||++t!=a?i:(a=n==null?0:n.length,!!a&&jn(a)&&Yn(f,a)&&(T(n)||un(n)))}function it(n,r){return n!=null&&tt(n,r,et)}var at=1,ft=2;function st(n,r){return B(n)&&Pn(r)?vn(M(n),r):function(e){var t=sr(e,n);return t===void 0&&t===r?it(e,n):Y(r,t,at|ft)}}function ut(n){return function(r){return r?.[n]}}function ot(n){return function(r){return bn(r,n)}}function gt(n){return B(n)?ut(M(n)):ot(n)}function Ln(n){return typeof n=="function"?n:n==null?cn:typeof n=="object"?T(n)?st(n[0],n[1]):rt(n):gt(n)}function lt(n,r){return n&&Zn(n,r,$)}function ct(n,r){return function(e,t){if(e==null)return e;if(!sn(e))return n(e,t);for(var a=e.length,i=-1,f=Object(e);++i<a&&t(f[i],i,f)!==!1;);return e}}var Z=ct(lt);function dt(n){return typeof n=="function"?n:cn}function $t(n,r){var e=T(n)?An:Z;return e(n,dt(r))}function pt(n,r){var e=[];return Z(n,function(t,a,i){r(t,a,i)&&e.push(t)}),e}function _t(n,r){var e=T(n)?Tn:pt;return e(n,Ln(r))}function At(n,r){return dn(r,function(e){return n[e]})}function St(n){return n==null?[]:At(n,$(n))}function Et(n){return n===void 0}function yt(n,r,e,t,a){return a(n,function(i,f,s){e=t?(t=!1,i):r(e,i,f,s)}),e}function It(n,r,e){var t=T(n)?or:yt,a=arguments.length<3;return t(n,Ln(r),e,a,Z)}var bt=1/0,Tt=m&&1/j(new m([,-0]))[1]==bt?function(n){return new m(n)}:Xn,ht=200;function Pt(n,r,e){var t=-1,a=Vn,i=n.length,f=!0,s=[],u=s;if(i>=ht){var d=r?null:Tt(n);if(d)return j(d);f=!1,a=En,u=new I}else u=r?[]:s;n:for(;++t<i;){var l=n[t],o=r?r(l):l;if(l=l!==0?l:0,f&&o===o){for(var c=u.length;c--;)if(u[c]===o)continue n;r&&u.push(o),s.push(l)}else a(u,o,e)||(u!==s&&u.push(o),s.push(l))}return s}export{Tn as A,pt as B,Ie as C,Xn as D,I as S,Pt as a,C as b,Ot as c,$t as d,N as e,_t as f,Ln as g,Jn as h,Et as i,Z as j,$ as k,dn as l,tt as m,yn as n,bn as o,dt as p,lt as q,It as r,it as s,M as t,fr as u,St as v,Vn as w,En as x,zn as y,br as z};
|
|
1
|
+
import{aH as S,aI as Rn,ax as T,aJ as w,aK as xn,aL as Mn,aw as sn,aM as mn,aN as un,aO as x,au as U,aP as Cn,aQ as on,aR as Fn,aS as E,aF as gn,aT as R,as as ln,aU as Dn,aV as D,aW as Gn,aX as Un,aY as _,aA as Nn,aZ as Bn,av as Kn,a_ as X,a$ as Hn,b0 as jn,az as Yn,ay as cn,aD as Zn,b1 as m}from"./mermaid.core-C_9cdmTh.js";var qn="[object Symbol]";function N(n){return typeof n=="symbol"||S(n)&&Rn(n)==qn}function dn(n,r){for(var e=-1,t=n==null?0:n.length,a=Array(t);++e<t;)a[e]=r(n[e],e,n);return a}var J=w?w.prototype:void 0,Q=J?J.toString:void 0;function pn(n){if(typeof n=="string")return n;if(T(n))return dn(n,pn)+"";if(N(n))return Q?Q.call(n):"";var r=n+"";return r=="0"&&1/n==-1/0?"-0":r}function Xn(){}function An(n,r){for(var e=-1,t=n==null?0:n.length;++e<t&&r(n[e],e,n)!==!1;);return n}function Jn(n,r,e,t){for(var a=n.length,i=e+-1;++i<a;)if(r(n[i],i,n))return i;return-1}function Qn(n){return n!==n}function Wn(n,r,e){for(var t=e-1,a=n.length;++t<a;)if(n[t]===r)return t;return-1}function zn(n,r,e){return r===r?Wn(n,r,e):Jn(n,Qn,e)}function Vn(n,r){var e=n==null?0:n.length;return!!e&&zn(n,r,0)>-1}function $(n){return sn(n)?xn(n):Mn(n)}var kn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,nr=/^\w*$/;function B(n,r){if(T(n))return!1;var e=typeof n;return e=="number"||e=="symbol"||e=="boolean"||n==null||N(n)?!0:nr.test(n)||!kn.test(n)||r!=null&&n in Object(r)}var rr=500;function er(n){var r=mn(n,function(t){return e.size===rr&&e.clear(),t}),e=r.cache;return r}var tr=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,ir=/\\(\\)?/g,ar=er(function(n){var r=[];return n.charCodeAt(0)===46&&r.push(""),n.replace(tr,function(e,t,a,i){r.push(a?i.replace(ir,"$1"):t||e)}),r});function fr(n){return n==null?"":pn(n)}function yn(n,r){return T(n)?n:B(n,r)?[n]:ar(fr(n))}function M(n){if(typeof n=="string"||N(n))return n;var r=n+"";return r=="0"&&1/n==-1/0?"-0":r}function bn(n,r){r=yn(r,n);for(var e=0,t=r.length;n!=null&&e<t;)n=n[M(r[e++])];return e&&e==t?n:void 0}function sr(n,r,e){var t=n==null?void 0:bn(n,r);return t===void 0?e:t}function K(n,r){for(var e=-1,t=r.length,a=n.length;++e<t;)n[a+e]=r[e];return n}var W=w?w.isConcatSpreadable:void 0;function ur(n){return T(n)||un(n)||!!(W&&n&&n[W])}function Ot(n,r,e,t,a){var i=-1,f=n.length;for(e||(e=ur),a||(a=[]);++i<f;){var s=n[i];e(s)?K(a,s):t||(a[a.length]=s)}return a}function or(n,r,e,t){var a=-1,i=n==null?0:n.length;for(t&&i&&(e=n[++a]);++a<i;)e=r(e,n[a],a,n);return e}function gr(n,r){return n&&x(r,$(r),n)}function lr(n,r){return n&&x(r,U(r),n)}function Tn(n,r){for(var e=-1,t=n==null?0:n.length,a=0,i=[];++e<t;){var f=n[e];r(f,e,n)&&(i[a++]=f)}return i}function hn(){return[]}var cr=Object.prototype,dr=cr.propertyIsEnumerable,z=Object.getOwnPropertySymbols,H=z?function(n){return n==null?[]:(n=Object(n),Tn(z(n),function(r){return dr.call(n,r)}))}:hn;function pr(n,r){return x(n,H(n),r)}var Ar=Object.getOwnPropertySymbols,wn=Ar?function(n){for(var r=[];n;)K(r,H(n)),n=Cn(n);return r}:hn;function yr(n,r){return x(n,wn(n),r)}function On(n,r,e){var t=r(n);return T(n)?t:K(t,e(n))}function G(n){return On(n,$,H)}function br(n){return On(n,U,wn)}var Tr=Object.prototype,hr=Tr.hasOwnProperty;function wr(n){var r=n.length,e=new n.constructor(r);return r&&typeof n[0]=="string"&&hr.call(n,"index")&&(e.index=n.index,e.input=n.input),e}function Or(n,r){var e=r?on(n.buffer):n.buffer;return new n.constructor(e,n.byteOffset,n.byteLength)}var $r=/\w*$/;function _r(n){var r=new n.constructor(n.source,$r.exec(n));return r.lastIndex=n.lastIndex,r}var V=w?w.prototype:void 0,k=V?V.valueOf:void 0;function Sr(n){return k?Object(k.call(n)):{}}var Er="[object Boolean]",Ir="[object Date]",Pr="[object Map]",vr="[object Number]",Lr="[object RegExp]",Rr="[object Set]",xr="[object String]",Mr="[object Symbol]",mr="[object ArrayBuffer]",Cr="[object DataView]",Fr="[object Float32Array]",Dr="[object Float64Array]",Gr="[object Int8Array]",Ur="[object Int16Array]",Nr="[object Int32Array]",Br="[object Uint8Array]",Kr="[object Uint8ClampedArray]",Hr="[object Uint16Array]",jr="[object Uint32Array]";function Yr(n,r,e){var t=n.constructor;switch(r){case mr:return on(n);case Er:case Ir:return new t(+n);case Cr:return Or(n,e);case Fr:case Dr:case Gr:case Ur:case Nr:case Br:case Kr:case Hr:case jr:return Fn(n,e);case Pr:return new t;case vr:case xr:return new t(n);case Lr:return _r(n);case Rr:return new t;case Mr:return Sr(n)}}var Zr="[object Map]";function qr(n){return S(n)&&E(n)==Zr}var nn=R&&R.isMap,Xr=nn?gn(nn):qr,Jr="[object Set]";function Qr(n){return S(n)&&E(n)==Jr}var rn=R&&R.isSet,Wr=rn?gn(rn):Qr,zr=1,Vr=2,kr=4,$n="[object Arguments]",ne="[object Array]",re="[object Boolean]",ee="[object Date]",te="[object Error]",_n="[object Function]",ie="[object GeneratorFunction]",ae="[object Map]",fe="[object Number]",Sn="[object Object]",se="[object RegExp]",ue="[object Set]",oe="[object String]",ge="[object Symbol]",le="[object WeakMap]",ce="[object ArrayBuffer]",de="[object DataView]",pe="[object Float32Array]",Ae="[object Float64Array]",ye="[object Int8Array]",be="[object Int16Array]",Te="[object Int32Array]",he="[object Uint8Array]",we="[object Uint8ClampedArray]",Oe="[object Uint16Array]",$e="[object Uint32Array]",g={};g[$n]=g[ne]=g[ce]=g[de]=g[re]=g[ee]=g[pe]=g[Ae]=g[ye]=g[be]=g[Te]=g[ae]=g[fe]=g[Sn]=g[se]=g[ue]=g[oe]=g[ge]=g[he]=g[we]=g[Oe]=g[$e]=!0;g[te]=g[_n]=g[le]=!1;function C(n,r,e,t,a,i){var f,s=r&zr,u=r&Vr,d=r&kr;if(f!==void 0)return f;if(!ln(n))return n;var l=T(n);if(l){if(f=wr(n),!s)return Dn(n,f)}else{var o=E(n),c=o==_n||o==ie;if(D(n))return Gn(n,s);if(o==Sn||o==$n||c&&!a){if(f=u||c?{}:Un(n),!s)return u?yr(n,lr(f,n)):pr(n,gr(f,n))}else{if(!g[o])return a?n:{};f=Yr(n,o,s)}}i||(i=new _);var h=i.get(n);if(h)return h;i.set(n,f),Wr(n)?n.forEach(function(p){f.add(C(p,r,e,p,n,i))}):Xr(n)&&n.forEach(function(p,A){f.set(A,C(p,r,e,A,n,i))});var y=d?u?br:G:u?U:$,b=l?void 0:y(n);return An(b||n,function(p,A){b&&(A=p,p=n[A]),Nn(f,A,C(p,r,e,A,n,i))}),f}var _e="__lodash_hash_undefined__";function Se(n){return this.__data__.set(n,_e),this}function Ee(n){return this.__data__.has(n)}function I(n){var r=-1,e=n==null?0:n.length;for(this.__data__=new Bn;++r<e;)this.add(n[r])}I.prototype.add=I.prototype.push=Se;I.prototype.has=Ee;function Ie(n,r){for(var e=-1,t=n==null?0:n.length;++e<t;)if(r(n[e],e,n))return!0;return!1}function En(n,r){return n.has(r)}var Pe=1,ve=2;function In(n,r,e,t,a,i){var f=e&Pe,s=n.length,u=r.length;if(s!=u&&!(f&&u>s))return!1;var d=i.get(n),l=i.get(r);if(d&&l)return d==r&&l==n;var o=-1,c=!0,h=e&ve?new I:void 0;for(i.set(n,r),i.set(r,n);++o<s;){var y=n[o],b=r[o];if(t)var p=f?t(b,y,o,r,n,i):t(y,b,o,n,r,i);if(p!==void 0){if(p)continue;c=!1;break}if(h){if(!Ie(r,function(A,O){if(!En(h,O)&&(y===A||a(y,A,e,t,i)))return h.push(O)})){c=!1;break}}else if(!(y===b||a(y,b,e,t,i))){c=!1;break}}return i.delete(n),i.delete(r),c}function Le(n){var r=-1,e=Array(n.size);return n.forEach(function(t,a){e[++r]=[a,t]}),e}function j(n){var r=-1,e=Array(n.size);return n.forEach(function(t){e[++r]=t}),e}var Re=1,xe=2,Me="[object Boolean]",me="[object Date]",Ce="[object Error]",Fe="[object Map]",De="[object Number]",Ge="[object RegExp]",Ue="[object Set]",Ne="[object String]",Be="[object Symbol]",Ke="[object ArrayBuffer]",He="[object DataView]",en=w?w.prototype:void 0,F=en?en.valueOf:void 0;function je(n,r,e,t,a,i,f){switch(e){case He:if(n.byteLength!=r.byteLength||n.byteOffset!=r.byteOffset)return!1;n=n.buffer,r=r.buffer;case Ke:return!(n.byteLength!=r.byteLength||!i(new X(n),new X(r)));case Me:case me:case De:return Kn(+n,+r);case Ce:return n.name==r.name&&n.message==r.message;case Ge:case Ne:return n==r+"";case Fe:var s=Le;case Ue:var u=tℜif(s||(s=j),n.size!=r.size&&!u)return!1;var d=f.get(n);if(d)return d==r;t|=xe,f.set(n,r);var l=In(s(n),s(r),t,a,i,f);return f.delete(n),l;case Be:if(F)return F.call(n)==F.call(r)}return!1}var Ye=1,Ze=Object.prototype,qe=Ze.hasOwnProperty;function Xe(n,r,e,t,a,i){var f=e&Ye,s=G(n),u=s.length,d=G(r),l=d.length;if(u!=l&&!f)return!1;for(var o=u;o--;){var c=s[o];if(!(f?c in r:qe.call(r,c)))return!1}var h=i.get(n),y=i.get(r);if(h&&y)return h==r&&y==n;var b=!0;i.set(n,r),i.set(r,n);for(var p=f;++o<u;){c=s[o];var A=n[c],O=r[c];if(t)var q=f?t(O,A,c,r,n,i):t(A,O,c,n,r,i);if(!(q===void 0?A===O||a(A,O,e,t,i):q)){b=!1;break}p||(p=c=="constructor")}if(b&&!p){var P=n.constructor,v=r.constructor;P!=v&&"constructor"in n&&"constructor"in r&&!(typeof P=="function"&&P instanceof P&&typeof v=="function"&&v instanceof v)&&(b=!1)}return i.delete(n),i.delete(r),b}var Je=1,tn="[object Arguments]",an="[object Array]",L="[object Object]",Qe=Object.prototype,fn=Qe.hasOwnProperty;function We(n,r,e,t,a,i){var f=T(n),s=T(r),u=f?an:E(n),d=s?an:E(r);u=u==tn?L:u,d=d==tn?L:d;var l=u==L,o=d==L,c=u==d;if(c&&D(n)){if(!D(r))return!1;f=!0,l=!1}if(c&&!l)return i||(i=new _),f||Hn(n)?In(n,r,e,t,a,i):je(n,r,u,e,t,a,i);if(!(e&Je)){var h=l&&fn.call(n,"__wrapped__"),y=o&&fn.call(r,"__wrapped__");if(h||y){var b=h?n.value():n,p=y?r.value():r;return i||(i=new _),a(b,p,e,t,i)}}return c?(i||(i=new _),Xe(n,r,e,t,a,i)):!1}function Y(n,r,e,t,a){return n===r?!0:n==null||r==null||!S(n)&&!S(r)?n!==n&&r!==r:We(n,r,e,t,Y,a)}var ze=1,Ve=2;function ke(n,r,e,t){var a=e.length,i=a;if(n==null)return!i;for(n=Object(n);a--;){var f=e[a];if(f[2]?f[1]!==n[f[0]]:!(f[0]in n))return!1}for(;++a<i;){f=e[a];var s=f[0],u=n[s],d=f[1];if(f[2]){if(u===void 0&&!(s in n))return!1}else{var l=new _,o;if(!(o===void 0?Y(d,u,ze|Ve,t,l):o))return!1}}return!0}function Pn(n){return n===n&&!ln(n)}function nt(n){for(var r=$(n),e=r.length;e--;){var t=r[e],a=n[t];r[e]=[t,a,Pn(a)]}return r}function vn(n,r){return function(e){return e==null?!1:e[n]===r&&(r!==void 0||n in Object(e))}}function rt(n){var r=nt(n);return r.length==1&&r[0][2]?vn(r[0][0],r[0][1]):function(e){return e===n||ke(e,n,r)}}function et(n,r){return n!=null&&r in Object(n)}function tt(n,r,e){r=yn(r,n);for(var t=-1,a=r.length,i=!1;++t<a;){var f=M(r[t]);if(!(i=n!=null&&e(n,f)))break;n=n[f]}return i||++t!=a?i:(a=n==null?0:n.length,!!a&&jn(a)&&Yn(f,a)&&(T(n)||un(n)))}function it(n,r){return n!=null&&tt(n,r,et)}var at=1,ft=2;function st(n,r){return B(n)&&Pn(r)?vn(M(n),r):function(e){var t=sr(e,n);return t===void 0&&t===r?it(e,n):Y(r,t,at|ft)}}function ut(n){return function(r){return r?.[n]}}function ot(n){return function(r){return bn(r,n)}}function gt(n){return B(n)?ut(M(n)):ot(n)}function Ln(n){return typeof n=="function"?n:n==null?cn:typeof n=="object"?T(n)?st(n[0],n[1]):rt(n):gt(n)}function lt(n,r){return n&&Zn(n,r,$)}function ct(n,r){return function(e,t){if(e==null)return e;if(!sn(e))return n(e,t);for(var a=e.length,i=-1,f=Object(e);++i<a&&t(f[i],i,f)!==!1;);return e}}var Z=ct(lt);function dt(n){return typeof n=="function"?n:cn}function $t(n,r){var e=T(n)?An:Z;return e(n,dt(r))}function pt(n,r){var e=[];return Z(n,function(t,a,i){r(t,a,i)&&e.push(t)}),e}function _t(n,r){var e=T(n)?Tn:pt;return e(n,Ln(r))}function At(n,r){return dn(r,function(e){return n[e]})}function St(n){return n==null?[]:At(n,$(n))}function Et(n){return n===void 0}function yt(n,r,e,t,a){return a(n,function(i,f,s){e=t?(t=!1,i):r(e,i,f,s)}),e}function It(n,r,e){var t=T(n)?or:yt,a=arguments.length<3;return t(n,Ln(r),e,a,Z)}var bt=1/0,Tt=m&&1/j(new m([,-0]))[1]==bt?function(n){return new m(n)}:Xn,ht=200;function Pt(n,r,e){var t=-1,a=Vn,i=n.length,f=!0,s=[],u=s;if(i>=ht){var d=r?null:Tt(n);if(d)return j(d);f=!1,a=En,u=new I}else u=r?[]:s;n:for(;++t<i;){var l=n[t],o=r?r(l):l;if(l=l!==0?l:0,f&&o===o){for(var c=u.length;c--;)if(u[c]===o)continue n;r&&u.push(o),s.push(l)}else a(u,o,e)||(u!==s&&u.push(o),s.push(l))}return s}export{Tn as A,pt as B,Ie as C,Xn as D,I as S,Pt as a,C as b,Ot as c,$t as d,N as e,_t as f,Ln as g,Jn as h,Et as i,Z as j,$ as k,dn as l,tt as m,yn as n,bn as o,dt as p,lt as q,It as r,it as s,M as t,fr as u,St as v,Vn as w,En as x,zn as y,br as z};
|
package/out/renderer/assets/{agent-details-page-CUVk_dQA.js → agent-details-page-CFeQgmpk.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as $,r as S,j as e,L as Z,T as B,B as c,S as L,b as R,d as F,e as q,f as x,X as G,g as j,c as U}from"./icon-
|
|
1
|
+
import{a as $,r as S,j as e,L as Z,T as B,B as c,S as L,b as R,d as F,e as q,f as x,X as G,g as j,c as U}from"./icon-BjW36U6M.js";import{g as W,a0 as V,f as E,J as f,M as P,a1 as _,a2 as M,a3 as ee,a4 as te,a5 as se,a6 as ae,a7 as I,a8 as H,a9 as ne,h as Y,aa as ie,ab as re,u as oe,ac as le,ad as ce,ae as de,af as me,B as ue,ag as xe,ah as he,ai as ge,aj as je,ak as O,al as fe,am as ye,an as pe}from"./index-Byb6o6Kr.js";import{S as be}from"./square-pen-D9Eba1sr.js";import{u as we,a as ve,b as Ce,c as Ne}from"./use-agent-like-mutation-CS4DoZ5N.js";/**
|
|
2
2
|
* @license lucide-react v0.507.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as p,j as e,c as j,r as m,S as y}from"./icon-
|
|
1
|
+
import{a as p,j as e,c as j,r as m,S as y}from"./icon-BjW36U6M.js";import{C as k}from"./compact-pagination-DqiXMGmM.js";import{P as v}from"./page-header-DwrySHPp.js";import{J as b,X as A,Y as h,Z as L,$ as N}from"./index-Byb6o6Kr.js";import{u as C,a as P,b as w,c as M}from"./use-agent-like-mutation-CS4DoZ5N.js";/**
|
|
2
2
|
* @license lucide-react v0.507.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|