pmxt 1.0.0b8__py3-none-any.whl → 1.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pmxt/__init__.py +1 -1
- pmxt/_server/__init__.py +0 -0
- pmxt/_server/bin/pmxt-ensure-server +158 -0
- pmxt/_server/server/bundled.js +84703 -0
- pmxt/client.py +7 -1
- pmxt/server_manager.py +33 -7
- {pmxt-1.0.0b8.dist-info → pmxt-1.0.3.dist-info}/METADATA +1 -1
- {pmxt-1.0.0b8.dist-info → pmxt-1.0.3.dist-info}/RECORD +13 -10
- pmxt_internal/__init__.py +1 -1
- pmxt_internal/api_client.py +1 -1
- pmxt_internal/configuration.py +1 -1
- {pmxt-1.0.0b8.dist-info → pmxt-1.0.3.dist-info}/WHEEL +0 -0
- {pmxt-1.0.0b8.dist-info → pmxt-1.0.3.dist-info}/top_level.txt +0 -0
pmxt/__init__.py
CHANGED
pmxt/_server/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* PMXT Server Launcher
|
|
5
|
+
*
|
|
6
|
+
* This script ensures the PMXT sidecar server is running.
|
|
7
|
+
* It's designed to be called by SDKs in any language (Python, Java, C#, Go, etc.)
|
|
8
|
+
*
|
|
9
|
+
* Behavior:
|
|
10
|
+
* 1. Check if server is already running (via lock file)
|
|
11
|
+
* 2. If running, exit successfully
|
|
12
|
+
* 3. If not running, spawn the server and wait for health check
|
|
13
|
+
* 4. Exit with code 0 on success, 1 on failure
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const path = require('path');
|
|
18
|
+
const os = require('os');
|
|
19
|
+
const { spawn } = require('child_process');
|
|
20
|
+
const http = require('http');
|
|
21
|
+
|
|
22
|
+
const LOCK_FILE = path.join(os.homedir(), '.pmxt', 'server.lock');
|
|
23
|
+
const DEFAULT_PORT = 3847;
|
|
24
|
+
const HEALTH_CHECK_TIMEOUT = 10000; // 10 seconds
|
|
25
|
+
const HEALTH_CHECK_INTERVAL = 100; // 100ms
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Check if the server is currently running
|
|
29
|
+
*/
|
|
30
|
+
function isServerRunning() {
|
|
31
|
+
try {
|
|
32
|
+
if (!fs.existsSync(LOCK_FILE)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const lockData = JSON.parse(fs.readFileSync(LOCK_FILE, 'utf-8'));
|
|
37
|
+
const { pid, port } = lockData;
|
|
38
|
+
|
|
39
|
+
// Check if process exists
|
|
40
|
+
try {
|
|
41
|
+
process.kill(pid, 0); // Signal 0 checks existence without killing
|
|
42
|
+
return { running: true, port };
|
|
43
|
+
} catch (err) {
|
|
44
|
+
// Process doesn't exist, remove stale lock file
|
|
45
|
+
fs.unlinkSync(LOCK_FILE);
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
} catch (err) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Wait for server to respond to health check
|
|
55
|
+
*/
|
|
56
|
+
function waitForHealth(port, timeout = HEALTH_CHECK_TIMEOUT) {
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
const startTime = Date.now();
|
|
59
|
+
|
|
60
|
+
const checkHealth = () => {
|
|
61
|
+
const req = http.get(`http://localhost:${port}/health`, (res) => {
|
|
62
|
+
if (res.statusCode === 200) {
|
|
63
|
+
resolve(true);
|
|
64
|
+
} else {
|
|
65
|
+
scheduleNextCheck();
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
req.on('error', () => {
|
|
70
|
+
scheduleNextCheck();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
req.setTimeout(1000);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const scheduleNextCheck = () => {
|
|
77
|
+
if (Date.now() - startTime > timeout) {
|
|
78
|
+
reject(new Error('Server health check timeout'));
|
|
79
|
+
} else {
|
|
80
|
+
setTimeout(checkHealth, HEALTH_CHECK_INTERVAL);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
checkHealth();
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Start the PMXT server
|
|
90
|
+
*/
|
|
91
|
+
async function startServer() {
|
|
92
|
+
// 1. Try to find the server binary/script
|
|
93
|
+
let serverCmd = 'pmxt-server';
|
|
94
|
+
let args = [];
|
|
95
|
+
|
|
96
|
+
// Check for Python-bundled server (when bundled in pip package)
|
|
97
|
+
const pythonBundledServer = path.join(__dirname, '..', 'server', 'bundled.js');
|
|
98
|
+
// Check for local dev bundled server
|
|
99
|
+
const localBundledServer = path.join(__dirname, '..', 'dist', 'server', 'bundled.js');
|
|
100
|
+
const localDistServer = path.join(__dirname, '..', 'dist', 'server', 'index.js');
|
|
101
|
+
const localBinServer = path.join(__dirname, 'pmxt-server');
|
|
102
|
+
|
|
103
|
+
if (fs.existsSync(pythonBundledServer)) {
|
|
104
|
+
serverCmd = 'node';
|
|
105
|
+
args = [pythonBundledServer];
|
|
106
|
+
} else if (fs.existsSync(localBundledServer)) {
|
|
107
|
+
serverCmd = 'node';
|
|
108
|
+
args = [localBundledServer];
|
|
109
|
+
} else if (fs.existsSync(localDistServer)) {
|
|
110
|
+
serverCmd = 'node';
|
|
111
|
+
args = [localDistServer];
|
|
112
|
+
} else if (fs.existsSync(localBinServer)) {
|
|
113
|
+
serverCmd = localBinServer;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Spawn server as detached process
|
|
117
|
+
const serverProcess = spawn(serverCmd, args, {
|
|
118
|
+
detached: true,
|
|
119
|
+
stdio: 'ignore',
|
|
120
|
+
env: process.env
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Detach from parent process
|
|
124
|
+
serverProcess.unref();
|
|
125
|
+
|
|
126
|
+
// Wait for server to be ready
|
|
127
|
+
await waitForHealth(DEFAULT_PORT);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Main entry point
|
|
132
|
+
*/
|
|
133
|
+
async function main() {
|
|
134
|
+
try {
|
|
135
|
+
// Check if server is already running
|
|
136
|
+
const serverStatus = isServerRunning();
|
|
137
|
+
|
|
138
|
+
if (serverStatus && serverStatus.running) {
|
|
139
|
+
// Server is running, verify it's healthy
|
|
140
|
+
try {
|
|
141
|
+
await waitForHealth(serverStatus.port, 2000);
|
|
142
|
+
process.exit(0);
|
|
143
|
+
} catch (err) {
|
|
144
|
+
// Server process exists but not responding, try to start fresh
|
|
145
|
+
console.error('Server process exists but not responding, starting fresh...');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Start the server
|
|
150
|
+
await startServer();
|
|
151
|
+
process.exit(0);
|
|
152
|
+
} catch (err) {
|
|
153
|
+
console.error('Failed to ensure server is running:', err.message);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
main();
|