@exulu/backend 1.48.2 → 1.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/dist/index.cjs +351 -42
  2. package/dist/index.d.cts +96 -1
  3. package/dist/index.d.ts +96 -1
  4. package/dist/index.js +340 -38
  5. package/ee/{markdown.ts → chunking/markdown.ts} +2 -2
  6. package/ee/python/README.md +295 -0
  7. package/ee/python/documents/processing/README.md +155 -0
  8. package/ee/{documents → python/documents}/processing/doc_processor.ts +25 -17
  9. package/ee/{documents/processing/pdf_to_markdown.py → python/documents/processing/document_to_markdown.py} +3 -10
  10. package/ee/python/setup.sh +180 -0
  11. package/package.json +14 -3
  12. package/scripts/postinstall.cjs +149 -0
  13. package/.agents/skills/mintlify/SKILL.md +0 -347
  14. package/.editorconfig +0 -15
  15. package/.eslintrc.json +0 -52
  16. package/.github/workflows/release-backend.yml +0 -38
  17. package/.husky/commit-msg +0 -1
  18. package/.jscpd.json +0 -18
  19. package/.mcp.json +0 -25
  20. package/.nvmrc +0 -1
  21. package/.prettierignore +0 -5
  22. package/.prettierrc.json +0 -12
  23. package/CHANGELOG.md +0 -8
  24. package/SECURITY.md +0 -5
  25. package/commitlint.config.js +0 -4
  26. package/devops/documentation/patch-older-releases.md +0 -42
  27. package/ee/documents/processing/build_pdf_processor.sh +0 -35
  28. package/ee/documents/processing/chunk_markdown.py +0 -263
  29. package/ee/documents/processing/pdf_processor.spec +0 -115
  30. package/eslint.config.js +0 -88
  31. package/jest.config.ts +0 -25
  32. package/mintlify-docs/.mintignore +0 -7
  33. package/mintlify-docs/AGENTS.md +0 -33
  34. package/mintlify-docs/CLAUDE.MD +0 -50
  35. package/mintlify-docs/CONTRIBUTING.md +0 -32
  36. package/mintlify-docs/LICENSE +0 -21
  37. package/mintlify-docs/README.md +0 -55
  38. package/mintlify-docs/ai-tools/claude-code.mdx +0 -43
  39. package/mintlify-docs/ai-tools/cursor.mdx +0 -39
  40. package/mintlify-docs/ai-tools/windsurf.mdx +0 -39
  41. package/mintlify-docs/api-reference/core-types/agent-types.mdx +0 -110
  42. package/mintlify-docs/api-reference/core-types/analytics-types.mdx +0 -95
  43. package/mintlify-docs/api-reference/core-types/configuration-types.mdx +0 -83
  44. package/mintlify-docs/api-reference/core-types/evaluation-types.mdx +0 -106
  45. package/mintlify-docs/api-reference/core-types/job-types.mdx +0 -135
  46. package/mintlify-docs/api-reference/core-types/overview.mdx +0 -73
  47. package/mintlify-docs/api-reference/core-types/prompt-types.mdx +0 -102
  48. package/mintlify-docs/api-reference/core-types/rbac-types.mdx +0 -163
  49. package/mintlify-docs/api-reference/core-types/session-types.mdx +0 -77
  50. package/mintlify-docs/api-reference/core-types/user-management.mdx +0 -112
  51. package/mintlify-docs/api-reference/core-types/workflow-types.mdx +0 -88
  52. package/mintlify-docs/api-reference/core-types.mdx +0 -585
  53. package/mintlify-docs/api-reference/dynamic-types.mdx +0 -851
  54. package/mintlify-docs/api-reference/endpoint/create.mdx +0 -4
  55. package/mintlify-docs/api-reference/endpoint/delete.mdx +0 -4
  56. package/mintlify-docs/api-reference/endpoint/get.mdx +0 -4
  57. package/mintlify-docs/api-reference/endpoint/webhook.mdx +0 -4
  58. package/mintlify-docs/api-reference/introduction.mdx +0 -661
  59. package/mintlify-docs/api-reference/mutations.mdx +0 -1012
  60. package/mintlify-docs/api-reference/openapi.json +0 -217
  61. package/mintlify-docs/api-reference/queries.mdx +0 -1154
  62. package/mintlify-docs/backend/introduction.mdx +0 -218
  63. package/mintlify-docs/changelog.mdx +0 -387
  64. package/mintlify-docs/community-edition.mdx +0 -304
  65. package/mintlify-docs/core/exulu-agent/api-reference.mdx +0 -894
  66. package/mintlify-docs/core/exulu-agent/configuration.mdx +0 -690
  67. package/mintlify-docs/core/exulu-agent/introduction.mdx +0 -552
  68. package/mintlify-docs/core/exulu-app/api-reference.mdx +0 -481
  69. package/mintlify-docs/core/exulu-app/configuration.mdx +0 -319
  70. package/mintlify-docs/core/exulu-app/introduction.mdx +0 -117
  71. package/mintlify-docs/core/exulu-authentication.mdx +0 -810
  72. package/mintlify-docs/core/exulu-chunkers/api-reference.mdx +0 -1011
  73. package/mintlify-docs/core/exulu-chunkers/configuration.mdx +0 -596
  74. package/mintlify-docs/core/exulu-chunkers/introduction.mdx +0 -403
  75. package/mintlify-docs/core/exulu-context/api-reference.mdx +0 -911
  76. package/mintlify-docs/core/exulu-context/configuration.mdx +0 -648
  77. package/mintlify-docs/core/exulu-context/introduction.mdx +0 -394
  78. package/mintlify-docs/core/exulu-database.mdx +0 -811
  79. package/mintlify-docs/core/exulu-default-agents.mdx +0 -545
  80. package/mintlify-docs/core/exulu-eval/api-reference.mdx +0 -772
  81. package/mintlify-docs/core/exulu-eval/configuration.mdx +0 -680
  82. package/mintlify-docs/core/exulu-eval/introduction.mdx +0 -459
  83. package/mintlify-docs/core/exulu-logging.mdx +0 -464
  84. package/mintlify-docs/core/exulu-otel.mdx +0 -670
  85. package/mintlify-docs/core/exulu-queues/api-reference.mdx +0 -648
  86. package/mintlify-docs/core/exulu-queues/configuration.mdx +0 -650
  87. package/mintlify-docs/core/exulu-queues/introduction.mdx +0 -474
  88. package/mintlify-docs/core/exulu-reranker/api-reference.mdx +0 -630
  89. package/mintlify-docs/core/exulu-reranker/configuration.mdx +0 -663
  90. package/mintlify-docs/core/exulu-reranker/introduction.mdx +0 -516
  91. package/mintlify-docs/core/exulu-tool/api-reference.mdx +0 -723
  92. package/mintlify-docs/core/exulu-tool/configuration.mdx +0 -805
  93. package/mintlify-docs/core/exulu-tool/introduction.mdx +0 -539
  94. package/mintlify-docs/core/exulu-variables/api-reference.mdx +0 -699
  95. package/mintlify-docs/core/exulu-variables/configuration.mdx +0 -736
  96. package/mintlify-docs/core/exulu-variables/introduction.mdx +0 -511
  97. package/mintlify-docs/development.mdx +0 -94
  98. package/mintlify-docs/docs.json +0 -248
  99. package/mintlify-docs/enterprise-edition.mdx +0 -538
  100. package/mintlify-docs/essentials/code.mdx +0 -35
  101. package/mintlify-docs/essentials/images.mdx +0 -59
  102. package/mintlify-docs/essentials/markdown.mdx +0 -88
  103. package/mintlify-docs/essentials/navigation.mdx +0 -87
  104. package/mintlify-docs/essentials/reusable-snippets.mdx +0 -110
  105. package/mintlify-docs/essentials/settings.mdx +0 -318
  106. package/mintlify-docs/favicon.svg +0 -3
  107. package/mintlify-docs/frontend/introduction.mdx +0 -39
  108. package/mintlify-docs/getting-started.mdx +0 -267
  109. package/mintlify-docs/guides/custom-agent.mdx +0 -608
  110. package/mintlify-docs/guides/first-agent.mdx +0 -315
  111. package/mintlify-docs/images/admin_ui.png +0 -0
  112. package/mintlify-docs/images/contexts.png +0 -0
  113. package/mintlify-docs/images/create_agents.png +0 -0
  114. package/mintlify-docs/images/evals.png +0 -0
  115. package/mintlify-docs/images/graphql.png +0 -0
  116. package/mintlify-docs/images/graphql_api.png +0 -0
  117. package/mintlify-docs/images/hero-dark.png +0 -0
  118. package/mintlify-docs/images/hero-light.png +0 -0
  119. package/mintlify-docs/images/hero.png +0 -0
  120. package/mintlify-docs/images/knowledge_sources.png +0 -0
  121. package/mintlify-docs/images/mcp.png +0 -0
  122. package/mintlify-docs/images/scaling.png +0 -0
  123. package/mintlify-docs/index.mdx +0 -411
  124. package/mintlify-docs/logo/dark.svg +0 -9
  125. package/mintlify-docs/logo/light.svg +0 -9
  126. package/mintlify-docs/partners.mdx +0 -558
  127. package/mintlify-docs/products.mdx +0 -77
  128. package/mintlify-docs/snippets/snippet-intro.mdx +0 -4
  129. package/mintlify-docs/styles.css +0 -207
  130. package/ngrok.bash +0 -1
  131. package/ngrok.md +0 -6
  132. package/ngrok.yml +0 -10
  133. package/release.config.cjs +0 -15
  134. package/skills-lock.json +0 -10
  135. package/types/context-processor.ts +0 -45
  136. package/types/enums/eval-types.ts +0 -5
  137. package/types/enums/field-types.ts +0 -1
  138. package/types/enums/jobs.ts +0 -11
  139. package/types/enums/statistics.ts +0 -13
  140. package/types/exulu-table-definition.ts +0 -79
  141. package/types/file-types.ts +0 -18
  142. package/types/models/agent-session.ts +0 -27
  143. package/types/models/agent.ts +0 -68
  144. package/types/models/context.ts +0 -53
  145. package/types/models/embedding.ts +0 -17
  146. package/types/models/eval-run.ts +0 -40
  147. package/types/models/exulu-agent-tool-config.ts +0 -11
  148. package/types/models/item.ts +0 -21
  149. package/types/models/job.ts +0 -8
  150. package/types/models/project.ts +0 -16
  151. package/types/models/rate-limiter-rules.ts +0 -7
  152. package/types/models/test-case.ts +0 -25
  153. package/types/models/tool.ts +0 -9
  154. package/types/models/user-role.ts +0 -12
  155. package/types/models/user.ts +0 -20
  156. package/types/models/variable.ts +0 -8
  157. package/types/models/vector-methods.ts +0 -7
  158. package/types/provider-config.ts +0 -21
  159. package/types/queue-config.ts +0 -16
  160. package/types/rbac-rights-modes.ts +0 -1
  161. package/types/statistics.ts +0 -20
  162. package/types/workflow.ts +0 -31
  163. /package/ee/{documents → python/documents}/THIRD_PARTY_LICENSES/docling.txt +0 -0
  164. /package/ee/{documents/processing → python}/requirements.txt +0 -0
@@ -0,0 +1,180 @@
1
+ #!/bin/bash
2
+ # Python Environment Setup Script
3
+ # Sets up Python virtual environment and installs dependencies for @exulu/backend
4
+
5
+ set -e # Exit on error
6
+
7
+ # Color codes for output
8
+ RED='\033[0;31m'
9
+ GREEN='\033[0;32m'
10
+ YELLOW='\033[1;33m'
11
+ BLUE='\033[0;34m'
12
+ NC='\033[0m' # No Color
13
+
14
+ # Get the directory where this script is located
15
+ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
16
+ VENV_DIR="${SCRIPT_DIR}/.venv"
17
+ REQUIREMENTS_FILE="${SCRIPT_DIR}/requirements.txt"
18
+
19
+ # Minimum Python version required
20
+ MIN_PYTHON_MAJOR=3
21
+ MIN_PYTHON_MINOR=10
22
+
23
+ echo -e "${BLUE}========================================${NC}"
24
+ echo -e "${BLUE} Exulu Python Environment Setup${NC}"
25
+ echo -e "${BLUE}========================================${NC}"
26
+ echo ""
27
+
28
+ # Function to print colored messages
29
+ print_success() {
30
+ echo -e "${GREEN}✓${NC} $1"
31
+ }
32
+
33
+ print_error() {
34
+ echo -e "${RED}✗${NC} $1"
35
+ }
36
+
37
+ print_warning() {
38
+ echo -e "${YELLOW}!${NC} $1"
39
+ }
40
+
41
+ print_info() {
42
+ echo -e "${BLUE}ℹ${NC} $1"
43
+ }
44
+
45
+ # Function to check Python version
46
+ check_python_version() {
47
+ local python_cmd=$1
48
+
49
+ if ! command -v "$python_cmd" &> /dev/null; then
50
+ return 1
51
+ fi
52
+
53
+ # Get Python version
54
+ local version=$($python_cmd --version 2>&1 | awk '{print $2}')
55
+ local major=$(echo "$version" | cut -d. -f1)
56
+ local minor=$(echo "$version" | cut -d. -f2)
57
+
58
+ # Check if version meets requirements
59
+ if [ "$major" -gt "$MIN_PYTHON_MAJOR" ] || \
60
+ ([ "$major" -eq "$MIN_PYTHON_MAJOR" ] && [ "$minor" -ge "$MIN_PYTHON_MINOR" ]); then
61
+ echo "$python_cmd"
62
+ return 0
63
+ fi
64
+
65
+ return 1
66
+ }
67
+
68
+ # Step 1: Check for Python installation
69
+ echo "Step 1: Checking Python installation..."
70
+ PYTHON_CMD=""
71
+
72
+ # Try different Python commands
73
+ for cmd in python3.12 python3.11 python3.10 python3 python; do
74
+ if PYTHON_CMD=$(check_python_version "$cmd"); then
75
+ break
76
+ fi
77
+ done
78
+
79
+ if [ -z "$PYTHON_CMD" ]; then
80
+ print_error "Python ${MIN_PYTHON_MAJOR}.${MIN_PYTHON_MINOR}+ is required but not found"
81
+ echo ""
82
+ echo "Please install Python ${MIN_PYTHON_MAJOR}.${MIN_PYTHON_MINOR} or higher:"
83
+ echo " - macOS: brew install python@3.12"
84
+ echo " - Ubuntu/Debian: sudo apt-get install python3.12"
85
+ echo " - Windows: Download from https://www.python.org/downloads/"
86
+ echo ""
87
+ exit 1
88
+ fi
89
+
90
+ PYTHON_VERSION=$($PYTHON_CMD --version 2>&1 | awk '{print $2}')
91
+ print_success "Found Python $PYTHON_VERSION at $(which $PYTHON_CMD)"
92
+
93
+ # Step 2: Check for pip
94
+ echo ""
95
+ echo "Step 2: Checking pip installation..."
96
+ if ! $PYTHON_CMD -m pip --version &> /dev/null; then
97
+ print_error "pip is not installed"
98
+ echo ""
99
+ echo "Please install pip:"
100
+ echo " curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py"
101
+ echo " $PYTHON_CMD get-pip.py"
102
+ echo ""
103
+ exit 1
104
+ fi
105
+
106
+ PIP_VERSION=$($PYTHON_CMD -m pip --version | awk '{print $2}')
107
+ print_success "Found pip $PIP_VERSION"
108
+
109
+ # Step 3: Create or update virtual environment
110
+ echo ""
111
+ echo "Step 3: Setting up virtual environment..."
112
+ if [ -d "$VENV_DIR" ]; then
113
+ # Check if virtual environment is valid
114
+ if [ -f "$VENV_DIR/bin/activate" ] && [ -f "$VENV_DIR/bin/python" ]; then
115
+ print_info "Virtual environment already exists at $VENV_DIR"
116
+ print_info "Updating existing environment..."
117
+ else
118
+ print_warning "Virtual environment is corrupted, recreating..."
119
+ rm -rf "$VENV_DIR"
120
+ $PYTHON_CMD -m venv "$VENV_DIR"
121
+ print_success "Virtual environment created"
122
+ fi
123
+ else
124
+ print_info "Creating virtual environment at $VENV_DIR"
125
+ $PYTHON_CMD -m venv "$VENV_DIR"
126
+ print_success "Virtual environment created"
127
+ fi
128
+
129
+ # Step 4: Activate virtual environment and upgrade pip
130
+ echo ""
131
+ echo "Step 4: Activating virtual environment..."
132
+ source "$VENV_DIR/bin/activate"
133
+ print_success "Virtual environment activated"
134
+
135
+ # Upgrade pip in virtual environment
136
+ print_info "Upgrading pip in virtual environment..."
137
+ pip install --upgrade pip > /dev/null 2>&1
138
+ print_success "pip upgraded to latest version"
139
+
140
+ # Step 5: Install dependencies
141
+ echo ""
142
+ echo "Step 5: Installing Python dependencies..."
143
+ if [ ! -f "$REQUIREMENTS_FILE" ]; then
144
+ print_error "Requirements file not found: $REQUIREMENTS_FILE"
145
+ exit 1
146
+ fi
147
+
148
+ print_info "Installing packages from requirements.txt..."
149
+ echo ""
150
+ pip install -r "$REQUIREMENTS_FILE"
151
+
152
+ print_success "All dependencies installed successfully"
153
+
154
+ # Step 6: Validate installation
155
+ echo ""
156
+ echo "Step 6: Validating installation..."
157
+
158
+ # Test critical imports
159
+ print_info "Testing critical imports..."
160
+ $PYTHON_CMD -c "import docling" 2>/dev/null && print_success "docling imported successfully" || print_error "Failed to import docling"
161
+ $PYTHON_CMD -c "import transformers" 2>/dev/null && print_success "transformers imported successfully" || print_error "Failed to import transformers"
162
+
163
+ # Step 7: Display summary
164
+ echo ""
165
+ echo -e "${GREEN}========================================${NC}"
166
+ echo -e "${GREEN} Setup Complete!${NC}"
167
+ echo -e "${GREEN}========================================${NC}"
168
+ echo ""
169
+ print_success "Python environment is ready to use"
170
+ echo ""
171
+ echo "Virtual environment location: $VENV_DIR"
172
+ echo "Python version: $PYTHON_VERSION"
173
+ echo ""
174
+ echo "To activate the virtual environment manually:"
175
+ echo " source $VENV_DIR/bin/activate"
176
+ echo ""
177
+ echo "To use Python scripts from TypeScript:"
178
+ echo " import { executePythonScript } from './utils/python-executor';"
179
+ echo ""
180
+ print_info "Your Python environment is now configured and ready!"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@exulu/backend",
3
3
  "author": "Qventu Bv.",
4
- "version": "1.48.2",
4
+ "version": "1.49.0",
5
5
  "main": "./dist/index.js",
6
6
  "private": false,
7
7
  "publishConfig": {
@@ -19,6 +19,7 @@
19
19
  },
20
20
  "scripts": {
21
21
  "preinstall": "node -e \"if (process.version !== 'v22.18.0') { console.error('❌ Wrong Node.js version. Expected v22.18.0, got ' + process.version); process.exit(1); }\"",
22
+ "postinstall": "node scripts/postinstall.cjs",
22
23
  "build": "tsup",
23
24
  "dev": "npm link && tsup --watch",
24
25
  "prepare": "husky",
@@ -38,7 +39,12 @@
38
39
  "audit:fix": "npm audit fix",
39
40
  "cpd": "jscpd src --reporters console",
40
41
  "cpd:report": "jscpd src --reporters console,html",
41
- "cpd:view": "serve cpd-report/html -l 3001"
42
+ "cpd:view": "serve cpd-report/html -l 3001",
43
+ "python:setup": "cd ee/python && ./setup.sh",
44
+ "python:install": "source ee/python/.venv/bin/activate && pip install -r ee/python/requirements.txt",
45
+ "python:validate": "source ee/python/.venv/bin/activate && python -c 'import docling; import transformers; print(\"✓ Python environment is working correctly\")'",
46
+ "python:clean": "rm -rf ee/python/.venv ee/python/__pycache__ ee/python/**/__pycache__ ee/python/**/*.pyc",
47
+ "python:rebuild": "npm run python:clean && npm run python:setup"
42
48
  },
43
49
  "keywords": [
44
50
  "exulu"
@@ -141,5 +147,10 @@
141
147
  "zod": "^3.25.76",
142
148
  "zod-to-json-schema": "^3.25.1",
143
149
  "zodex": "^0.18.2"
144
- }
150
+ },
151
+ "files": [
152
+ "dist",
153
+ "ee",
154
+ "scripts/postinstall.cjs"
155
+ ]
145
156
  }
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Postinstall script for @exulu/backend
4
+ *
5
+ * Automatically sets up the Python environment when the package is installed.
6
+ * Can be skipped by setting SKIP_PYTHON_SETUP=1 environment variable.
7
+ */
8
+
9
+ const { exec } = require('child_process');
10
+ const { promisify } = require('util');
11
+ const { existsSync } = require('fs');
12
+ const { resolve, join } = require('path');
13
+
14
+ const execAsync = promisify(exec);
15
+
16
+ // ANSI color codes
17
+ const colors = {
18
+ reset: '\x1b[0m',
19
+ green: '\x1b[32m',
20
+ yellow: '\x1b[33m',
21
+ blue: '\x1b[34m',
22
+ red: '\x1b[31m',
23
+ };
24
+
25
+ /**
26
+ * Check if we should skip Python setup
27
+ */
28
+ function shouldSkipSetup() {
29
+ // Skip if environment variable is set
30
+ if (process.env.SKIP_PYTHON_SETUP === '1' || process.env.SKIP_PYTHON_SETUP === 'true') {
31
+ return true;
32
+ }
33
+
34
+ // Skip in CI environments by default (unless explicitly enabled)
35
+ if (process.env.CI && !process.env.SETUP_PYTHON_IN_CI) {
36
+ return true;
37
+ }
38
+
39
+ return false;
40
+ }
41
+
42
+ /**
43
+ * Check if Python environment already exists
44
+ */
45
+ function pythonEnvironmentExists() {
46
+ const venvPath = resolve(__dirname, '..', 'ee/python/.venv');
47
+ const pythonPath = join(venvPath, 'bin', 'python');
48
+ return existsSync(venvPath) && existsSync(pythonPath);
49
+ }
50
+
51
+ /**
52
+ * Run the Python setup script
53
+ */
54
+ async function setupPythonEnvironment() {
55
+ const setupScriptPath = resolve(__dirname, '..', 'ee/python/setup.sh');
56
+
57
+ if (!existsSync(setupScriptPath)) {
58
+ console.error(`${colors.red}✗${colors.reset} Setup script not found: ${setupScriptPath}`);
59
+ return false;
60
+ }
61
+
62
+ try {
63
+ console.log(`${colors.blue}Running Python environment setup...${colors.reset}`);
64
+ console.log('');
65
+
66
+ const { stdout, stderr } = await execAsync(`bash "${setupScriptPath}"`, {
67
+ cwd: resolve(__dirname, '..'),
68
+ timeout: 600000, // 10 minutes
69
+ maxBuffer: 10 * 1024 * 1024,
70
+ });
71
+
72
+ // Show output
73
+ if (stdout) console.log(stdout);
74
+ if (stderr) console.error(stderr);
75
+
76
+ return true;
77
+ } catch (error) {
78
+ console.error(`${colors.red}✗${colors.reset} Python setup failed:`, error.message);
79
+ if (error.stdout) console.log(error.stdout);
80
+ if (error.stderr) console.error(error.stderr);
81
+ return false;
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Main postinstall function
87
+ */
88
+ async function main() {
89
+ console.log('');
90
+ console.log(`${colors.blue}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${colors.reset}`);
91
+ console.log(`${colors.blue} @exulu/backend - Post-install Setup${colors.reset}`);
92
+ console.log(`${colors.blue}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${colors.reset}`);
93
+ console.log('');
94
+
95
+ // Check if we should skip setup
96
+ if (shouldSkipSetup()) {
97
+ console.log(`${colors.yellow}⊘${colors.reset} Skipping Python setup (SKIP_PYTHON_SETUP=1)`);
98
+ console.log('');
99
+ console.log('To set up Python later, run:');
100
+ console.log(` ${colors.green}npx @exulu/backend setup-python${colors.reset}`);
101
+ console.log(' or in your code:');
102
+ console.log(` ${colors.green}import { setupPythonEnvironment } from '@exulu/backend';${colors.reset}`);
103
+ console.log(` ${colors.green}await setupPythonEnvironment();${colors.reset}`);
104
+ console.log('');
105
+ return;
106
+ }
107
+
108
+ // Check if already exists
109
+ if (pythonEnvironmentExists()) {
110
+ console.log(`${colors.green}✓${colors.reset} Python environment already set up`);
111
+ console.log('');
112
+ console.log('To rebuild, run:');
113
+ console.log(` ${colors.green}import { setupPythonEnvironment } from '@exulu/backend';${colors.reset}`);
114
+ console.log(` ${colors.green}await setupPythonEnvironment({ force: true });${colors.reset}`);
115
+ console.log('');
116
+ return;
117
+ }
118
+
119
+ // Run setup
120
+ const success = await setupPythonEnvironment();
121
+
122
+ if (success) {
123
+ console.log('');
124
+ console.log(`${colors.green}✓${colors.reset} Python environment ready!`);
125
+ console.log('');
126
+ } else {
127
+ console.log('');
128
+ console.log(`${colors.yellow}!${colors.reset} Python setup failed or was skipped`);
129
+ console.log('');
130
+ console.log('This is not critical - you can set up Python later by running:');
131
+ console.log(` ${colors.green}import { setupPythonEnvironment } from '@exulu/backend';${colors.reset}`);
132
+ console.log(` ${colors.green}await setupPythonEnvironment();${colors.reset}`);
133
+ console.log('');
134
+ console.log('Requirements:');
135
+ console.log(' - Python 3.10 or higher');
136
+ console.log(' - pip package manager');
137
+ console.log('');
138
+ }
139
+
140
+ console.log(`${colors.blue}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${colors.reset}`);
141
+ console.log('');
142
+ }
143
+
144
+ // Run postinstall
145
+ main().catch((error) => {
146
+ console.error('Postinstall error:', error);
147
+ // Don't exit with error code - postinstall failures shouldn't block npm install
148
+ process.exit(0);
149
+ });