machinaos 0.0.7 → 0.0.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "machinaos",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Open source workflow automation platform with AI agents, React Flow, and n8n-inspired architecture",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -71,7 +71,7 @@
71
71
  "deploy": "bash deploy.sh",
72
72
  "deploy:gcp": "bash deploy.sh",
73
73
  "prepublishOnly": "node -e \"const p=require('./package.json'); if(!p.bin||!p.version){process.exit(1)}\"",
74
- "postinstall": "node scripts/build.js"
74
+ "postinstall": "node scripts/postinstall.js"
75
75
  },
76
76
  "dependencies": {
77
77
  "concurrently": "^9.2.1",
package/scripts/build.js CHANGED
@@ -32,7 +32,6 @@ if (isCI && isPostInstall) {
32
32
  process.exit(0);
33
33
  }
34
34
 
35
-
36
35
  // Ensure Python UTF-8 encoding
37
36
  process.env.PYTHONUTF8 = '1';
38
37
 
@@ -0,0 +1,178 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Optional binary download script for MachinaOS.
4
+ * Downloads pre-built WhatsApp RPC server binary from GitHub Releases.
5
+ *
6
+ * Skipped if:
7
+ * - MACHINAOS_SKIP_BINARY_DOWNLOAD=1
8
+ * - CI environment (CI=true)
9
+ * - Go is installed (can build from source)
10
+ *
11
+ * Force download even if Go installed:
12
+ * - MACHINAOS_FORCE_BINARY_DOWNLOAD=1
13
+ */
14
+ import { execSync } from 'child_process';
15
+ import { createWriteStream, existsSync, mkdirSync, chmodSync, readFileSync } from 'fs';
16
+ import { resolve, dirname } from 'path';
17
+ import { fileURLToPath } from 'url';
18
+ import https from 'https';
19
+
20
+ const __dirname = dirname(fileURLToPath(import.meta.url));
21
+ const ROOT = resolve(__dirname, '..');
22
+ const WHATSAPP_BIN_DIR = resolve(ROOT, 'server/whatsapp-rpc/bin');
23
+
24
+ // Read version from package.json
25
+ const pkg = JSON.parse(readFileSync(resolve(ROOT, 'package.json'), 'utf-8'));
26
+ const VERSION = pkg.version;
27
+
28
+ // GitHub release URL
29
+ const GITHUB_REPO = 'trohitg/MachinaOS';
30
+ const BASE_URL = `https://github.com/${GITHUB_REPO}/releases/download/v${VERSION}`;
31
+
32
+ // Platform detection
33
+ function getPlatformInfo() {
34
+ const osMap = { 'win32': 'windows', 'darwin': 'darwin', 'linux': 'linux' };
35
+ const archMap = { 'x64': 'amd64', 'arm64': 'arm64' };
36
+
37
+ const os = osMap[process.platform];
38
+ const goarch = archMap[process.arch];
39
+
40
+ if (!os || !goarch) {
41
+ return null;
42
+ }
43
+
44
+ const ext = process.platform === 'win32' ? '.exe' : '';
45
+ return { os, goarch, ext };
46
+ }
47
+
48
+ // Check if Go is installed
49
+ function hasGo() {
50
+ try {
51
+ execSync('go version', { stdio: 'ignore' });
52
+ return true;
53
+ } catch {
54
+ return false;
55
+ }
56
+ }
57
+
58
+ // Download file with redirect handling
59
+ function downloadFile(url, dest) {
60
+ return new Promise((resolve, reject) => {
61
+ const request = (currentUrl, redirectCount = 0) => {
62
+ if (redirectCount > 5) {
63
+ reject(new Error('Too many redirects'));
64
+ return;
65
+ }
66
+
67
+ const client = currentUrl.startsWith('https') ? https : require('http');
68
+
69
+ client.get(currentUrl, (response) => {
70
+ // Handle redirects (GitHub releases redirect to CDN)
71
+ if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) {
72
+ request(response.headers.location, redirectCount + 1);
73
+ return;
74
+ }
75
+
76
+ if (response.statusCode !== 200) {
77
+ reject(new Error(`HTTP ${response.statusCode}`));
78
+ return;
79
+ }
80
+
81
+ const file = createWriteStream(dest);
82
+ const totalBytes = parseInt(response.headers['content-length'], 10);
83
+ let downloadedBytes = 0;
84
+
85
+ response.on('data', (chunk) => {
86
+ downloadedBytes += chunk.length;
87
+ if (totalBytes) {
88
+ const percent = ((downloadedBytes / totalBytes) * 100).toFixed(1);
89
+ process.stdout.write(`\r Downloading: ${percent}%`);
90
+ }
91
+ });
92
+
93
+ response.pipe(file);
94
+ file.on('finish', () => {
95
+ file.close();
96
+ console.log(' Done');
97
+ resolve();
98
+ });
99
+ file.on('error', (err) => {
100
+ file.close();
101
+ reject(err);
102
+ });
103
+ }).on('error', reject);
104
+ };
105
+
106
+ request(url);
107
+ });
108
+ }
109
+
110
+ // Main
111
+ async function main() {
112
+ // Skip conditions
113
+ if (process.env.MACHINAOS_SKIP_BINARY_DOWNLOAD === '1') {
114
+ console.log('Skipping binary download (MACHINAOS_SKIP_BINARY_DOWNLOAD=1)');
115
+ return;
116
+ }
117
+
118
+ if (process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true') {
119
+ console.log('Skipping binary download (CI environment)');
120
+ return;
121
+ }
122
+
123
+ // Check if Go is installed - prefer source build
124
+ if (hasGo()) {
125
+ if (process.env.MACHINAOS_FORCE_BINARY_DOWNLOAD !== '1') {
126
+ console.log('Go is installed - will build from source');
127
+ return;
128
+ }
129
+ console.log('Go is installed but MACHINAOS_FORCE_BINARY_DOWNLOAD=1, downloading anyway');
130
+ }
131
+
132
+ const platformInfo = getPlatformInfo();
133
+ if (!platformInfo) {
134
+ console.log(`Unsupported platform: ${process.platform}/${process.arch}`);
135
+ return;
136
+ }
137
+
138
+ const { os, goarch, ext } = platformInfo;
139
+ const binaryName = `whatsapp-rpc-server-${os}-${goarch}${ext}`;
140
+ const downloadUrl = `${BASE_URL}/${binaryName}`;
141
+ const destPath = resolve(WHATSAPP_BIN_DIR, `whatsapp-rpc-server${ext}`);
142
+
143
+ console.log(`\nDownloading pre-built WhatsApp RPC binary...`);
144
+ console.log(` Version: v${VERSION}`);
145
+ console.log(` Platform: ${os}/${goarch}`);
146
+
147
+ // Create bin directory
148
+ if (!existsSync(WHATSAPP_BIN_DIR)) {
149
+ mkdirSync(WHATSAPP_BIN_DIR, { recursive: true });
150
+ }
151
+
152
+ // Check if binary already exists
153
+ if (existsSync(destPath)) {
154
+ console.log(` Binary already exists: ${destPath}`);
155
+ return;
156
+ }
157
+
158
+ // Download binary
159
+ try {
160
+ await downloadFile(downloadUrl, destPath);
161
+ } catch (error) {
162
+ console.error(`\nFailed to download binary: ${error.message}`);
163
+ console.log('Will attempt to build from source instead.');
164
+ return;
165
+ }
166
+
167
+ // Set executable permission (Unix only)
168
+ if (process.platform !== 'win32') {
169
+ chmodSync(destPath, 0o755);
170
+ }
171
+
172
+ console.log(`Binary downloaded: ${destPath}`);
173
+ }
174
+
175
+ main().catch((err) => {
176
+ // Don't fail the install - just log and continue
177
+ console.error('Binary download error:', err.message);
178
+ });
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Postinstall script for MachinaOS.
4
+ * Outputs to stderr so npm shows the progress (npm suppresses stdout during postinstall).
5
+ *
6
+ * Scenarios:
7
+ * 1. npm install -g machinaos → Run full install with output
8
+ * 2. npm install (local) → Run full install with output
9
+ * 3. GitHub Actions CI → Skip (workflow handles build separately)
10
+ *
11
+ * Runs:
12
+ * 1. download-binaries.js (optional binary download)
13
+ * 2. build.js (full build)
14
+ */
15
+ import { spawn } from 'child_process';
16
+ import { resolve, dirname } from 'path';
17
+ import { fileURLToPath } from 'url';
18
+
19
+ const __dirname = dirname(fileURLToPath(import.meta.url));
20
+ const ROOT = resolve(__dirname, '..');
21
+
22
+ // Output to stderr so npm shows it during install
23
+ const print = (msg) => process.stderr.write(msg + '\n');
24
+
25
+ // Environment detection
26
+ const isCI = process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true';
27
+
28
+ // Skip in CI - GitHub Actions workflow handles build separately
29
+ if (isCI) {
30
+ print('CI environment detected, skipping postinstall.');
31
+ process.exit(0);
32
+ }
33
+
34
+ print('');
35
+ print('========================================');
36
+ print(' MachinaOS - Installing...');
37
+ print('========================================');
38
+ print('');
39
+
40
+ // Run a script and pipe output to stderr
41
+ function runScript(scriptPath) {
42
+ return new Promise((resolve, reject) => {
43
+ const child = spawn(process.execPath, [scriptPath], {
44
+ cwd: ROOT,
45
+ stdio: ['inherit', process.stderr, 'inherit'],
46
+ env: { ...process.env, FORCE_COLOR: '1' }
47
+ });
48
+
49
+ child.on('error', reject);
50
+ child.on('close', (code) => {
51
+ if (code === 0) {
52
+ resolve();
53
+ } else {
54
+ reject(new Error(`Script exited with code ${code}`));
55
+ }
56
+ });
57
+ });
58
+ }
59
+
60
+ async function main() {
61
+ try {
62
+ // Step 1: Try to download pre-built binaries (optional, non-fatal)
63
+ print('[1/2] Checking for pre-built binaries...');
64
+ try {
65
+ await runScript(resolve(__dirname, 'download-binaries.js'));
66
+ } catch (e) {
67
+ print(' Binary download skipped or failed, will build from source.');
68
+ }
69
+
70
+ // Step 2: Run the full build
71
+ print('');
72
+ print('[2/2] Building MachinaOS...');
73
+ print('');
74
+ await runScript(resolve(__dirname, 'build.js'));
75
+
76
+ print('');
77
+ print('========================================');
78
+ print(' MachinaOS installed successfully!');
79
+ print('========================================');
80
+ print('');
81
+ print('Run: machinaos start');
82
+ print('Open: http://localhost:3000');
83
+ print('');
84
+
85
+ } catch (err) {
86
+ print('');
87
+ print('========================================');
88
+ print(' Installation failed!');
89
+ print('========================================');
90
+ print('');
91
+ print(`Error: ${err.message}`);
92
+ print('');
93
+ print('Try running manually:');
94
+ print(' machinaos build');
95
+ print('');
96
+ process.exit(1);
97
+ }
98
+ }
99
+
100
+ main();
package/server/uv.lock CHANGED
@@ -2582,15 +2582,15 @@ wheels = [
2582
2582
 
2583
2583
  [[package]]
2584
2584
  name = "sqlmodel"
2585
- version = "0.0.31"
2585
+ version = "0.0.32"
2586
2586
  source = { registry = "https://pypi.org/simple" }
2587
2587
  dependencies = [
2588
2588
  { name = "pydantic" },
2589
2589
  { name = "sqlalchemy" },
2590
2590
  ]
2591
- sdist = { url = "https://files.pythonhosted.org/packages/56/b8/e7cd6def4a773f25d6e29ffce63ccbfd6cf9488b804ab6fb9b80d334b39d/sqlmodel-0.0.31.tar.gz", hash = "sha256:2d41a8a9ee05e40736e2f9db8ea28cbfe9b5d4e5a18dd139e80605025e0c516c", size = 94952, upload-time = "2025-12-28T12:35:01.436Z" }
2591
+ sdist = { url = "https://files.pythonhosted.org/packages/d1/89/67f8964f3b2ed073fa4e95201e708291935d00e3600f36f09c1be3e279fe/sqlmodel-0.0.32.tar.gz", hash = "sha256:48e8fe4c8c3d7d8bf8468db17fa92ca680421e86cfec8b352217ef40736767be", size = 94140, upload-time = "2026-02-01T18:19:14.752Z" }
2592
2592
  wheels = [
2593
- { url = "https://files.pythonhosted.org/packages/6c/72/5aa5be921800f6418a949a73c9bb7054890881143e6bc604a93d228a95a3/sqlmodel-0.0.31-py3-none-any.whl", hash = "sha256:6d946d56cac4c2db296ba1541357cee2e795d68174e2043cd138b916794b1513", size = 27093, upload-time = "2025-12-28T12:35:00.108Z" },
2593
+ { url = "https://files.pythonhosted.org/packages/ed/de/d9b40ed2c570fd612c2abd57e4d9084a9d8eb1797447e2ce897b77b1c4b2/sqlmodel-0.0.32-py3-none-any.whl", hash = "sha256:d62f0702599592046c1a136d3512feab3d5a80e2988642ef0ed2c89b9b8b297b", size = 27416, upload-time = "2026-02-01T18:19:15.992Z" },
2594
2594
  ]
2595
2595
 
2596
2596
  [[package]]
@@ -97,13 +97,22 @@ async function status() {
97
97
  }
98
98
 
99
99
  async function build() {
100
+ const bin = join(BIN_DIR, BIN);
101
+
102
+ // Skip if binary already exists (e.g., downloaded from GitHub Releases)
103
+ if (existsSync(bin)) {
104
+ log(`Binary already exists: ${BIN} (${(statSync(bin).size / 1024 / 1024).toFixed(1)}MB)`, 'green');
105
+ return;
106
+ }
107
+
108
+ // Build from source requires Go
100
109
  if (!hasGo()) {
101
- log('Go is not installed. Install from: https://go.dev/dl/', 'red');
110
+ log('Go is not installed and no pre-built binary found.', 'red');
111
+ log('Install Go from: https://go.dev/dl/', 'yellow');
102
112
  process.exit(1);
103
113
  }
104
- const bin = join(BIN_DIR, BIN);
114
+
105
115
  if (!existsSync(BIN_DIR)) { await execa('mkdir', ['-p', BIN_DIR]); }
106
- if (existsSync(bin)) unlinkSync(bin);
107
116
  await execa('go', ['build', '-o', bin, './src/go/cmd/server'], { cwd: ROOT, stdio: 'inherit' });
108
117
  log(`Built: ${BIN} (${(statSync(bin).size / 1024 / 1024).toFixed(1)}MB)`, 'green');
109
118
  }