omniwire 3.4.0 → 3.4.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.
@@ -1 +1 @@
1
- {"session_id":"8ef02123-7368-447d-82e3-ee14a27328b0","transcript_path":"C:\\Users\\Admin\\.claude\\projects\\C--Users-Admin\\8ef02123-7368-447d-82e3-ee14a27328b0.jsonl","cwd":"C:\\Users\\Admin\\omniwire","model":{"id":"claude-opus-4-6[1m]","display_name":"Opus 4.6 (1M context)"},"workspace":{"current_dir":"C:\\Users\\Admin\\omniwire","project_dir":"C:\\Users\\Admin","added_dirs":["C:/Users/Admin"]},"version":"2.1.87","output_style":{"name":"default"},"cost":{"total_cost_usd":17.91894630000001,"total_duration_ms":3140566,"total_api_duration_ms":2378114,"total_lines_added":474,"total_lines_removed":126},"context_window":{"total_input_tokens":180562,"total_output_tokens":100001,"context_window_size":1000000,"current_usage":{"input_tokens":1,"output_tokens":359,"cache_creation_input_tokens":356,"cache_read_input_tokens":184970},"used_percentage":19,"remaining_percentage":81},"exceeds_200k_tokens":false,"rate_limits":{"five_hour":{"used_percentage":2,"resets_at":1774846800},"seven_day":{"used_percentage":41,"resets_at":1775206800}}}
1
+ {"session_id":"8ef02123-7368-447d-82e3-ee14a27328b0","transcript_path":"C:\\Users\\Admin\\.claude\\projects\\C--Users-Admin\\8ef02123-7368-447d-82e3-ee14a27328b0.jsonl","cwd":"C:\\Users\\Admin\\omniwire","model":{"id":"claude-opus-4-6[1m]","display_name":"Opus 4.6 (1M context)"},"workspace":{"current_dir":"C:\\Users\\Admin\\omniwire","project_dir":"C:\\Users\\Admin","added_dirs":["C:/Users/Admin"]},"version":"2.1.87","output_style":{"name":"default"},"cost":{"total_cost_usd":20.34991630000001,"total_duration_ms":3367671,"total_api_duration_ms":2589826,"total_lines_added":563,"total_lines_removed":143},"context_window":{"total_input_tokens":180627,"total_output_tokens":109433,"context_window_size":1000000,"current_usage":{"input_tokens":1,"output_tokens":277,"cache_creation_input_tokens":374,"cache_read_input_tokens":197273},"used_percentage":20,"remaining_percentage":80},"exceeds_200k_tokens":false,"rate_limits":{"five_hour":{"used_percentage":3,"resets_at":1774846800},"seven_day":{"used_percentage":41,"resets_at":1775206800}}}
package/README.md CHANGED
@@ -687,7 +687,8 @@ omniwire/
687
687
 
688
688
  | Version | Date | Changes |
689
689
  |---------|------|---------|
690
- | **v3.4.0** | 2026-03-30 | Rewrite: `omniwire_scrape` OmniMesh-routed Scrapling with auto-install, VPN routing, adaptive selectors, XPath, bulk sessions. install/status actions. Full README audit (88 tools everywhere). |
690
+ | **v3.4.1** | 2026-03-30 | Cross-OS: `omniwire_scrape` install works on Linux (systemd), macOS (launchd), Windows, Docker (nohup). Auto-upgrades deps + browsers. Python/pip path detection. |
691
+ | **v3.4.0** | 2026-03-30 | Rewrite: `omniwire_scrape` — OmniMesh-routed Scrapling with auto-install, VPN routing, adaptive selectors, XPath, bulk sessions. install/status actions. Full README audit (88 tools). |
691
692
  | **v3.3.1** | 2026-03-30 | New: `omniwire_scrape` tool — Scrapling-powered web scraping (static/browser/stealth modes, Cloudflare bypass, TLS spoofing). |
692
693
  | **v3.3.0** | 2026-03-30 | New: `omniwire_coc` tool — unified CyberBase + Obsidian + Canvas sync. Auto-creates vault + canvas. `mirror-db` exports entire DB as .md. Configurable vault via `OMNIWIRE_VAULT_ROOT` env. |
693
694
  | **v3.2.2** | 2026-03-30 | Fix: sync GitHub/npm metadata — badge, description, mermaid diagram all reflect 86 tools |
@@ -4175,13 +4175,25 @@ echo "port-knock configured: ${ports.join(' -> ')} -> port ${target}"`;
4175
4175
  const target = targetNode ?? 'contabo';
4176
4176
  // --- Action: install ---
4177
4177
  if (action === 'install') {
4178
- const installScript = `
4179
- pip install "scrapling[all]" 2>&1 | tail -3
4178
+ // Detect target OS for cross-platform install
4179
+ const targetOs = remoteNodes().find(n => n.id === target)?.os ?? 'linux';
4180
+ const pyCmd = targetOs === 'windows' ? 'python' : 'python3';
4181
+ const pipCmd = targetOs === 'windows' ? 'pip' : 'pip3';
4182
+ const installScript = targetOs === 'windows'
4183
+ ? `${pipCmd} install --upgrade "scrapling[all]" 2>&1 | Select-Object -Last 3; scrapling install 2>&1 | Select-Object -Last 3; ${pyCmd} -c "import scrapling; print('scrapling', scrapling.__version__)" 2>&1`
4184
+ : `
4185
+ # Ensure Python 3.10+ and pip are available
4186
+ command -v ${pyCmd} &>/dev/null || { echo "ERROR: ${pyCmd} not found — install Python 3.10+"; exit 1; }
4187
+ command -v ${pipCmd} &>/dev/null || { ${pyCmd} -m ensurepip --upgrade 2>&1 | tail -1; }
4188
+ # Install/upgrade Scrapling and all dependencies
4189
+ ${pipCmd} install --upgrade "scrapling[all]" 2>&1 | tail -3
4190
+ # Download/update Playwright + Camoufox browsers
4180
4191
  scrapling install 2>&1 | tail -3
4181
- python3 -c "import scrapling; print('scrapling', scrapling.__version__)" 2>&1
4182
- # Set up systemd service if not exists
4183
- if [ ! -f /etc/systemd/system/scrapling-mcp.service ]; then
4184
- cat > /etc/systemd/system/scrapling-mcp.service << 'UNIT'
4192
+ ${pyCmd} -c "import scrapling; print('scrapling', scrapling.__version__)" 2>&1
4193
+ # Set up systemd service if available
4194
+ if command -v systemctl &>/dev/null; then
4195
+ if [ ! -f /etc/systemd/system/scrapling-mcp.service ]; then
4196
+ cat > /etc/systemd/system/scrapling-mcp.service << 'UNIT'
4185
4197
  [Unit]
4186
4198
  Description=Scrapling MCP HTTP Server
4187
4199
  After=network.target
@@ -4194,20 +4206,50 @@ Environment=HOME=/root
4194
4206
  [Install]
4195
4207
  WantedBy=multi-user.target
4196
4208
  UNIT
4197
- systemctl daemon-reload
4198
- systemctl enable scrapling-mcp
4199
- systemctl start scrapling-mcp
4200
- echo "systemd service created and started"
4209
+ systemctl daemon-reload
4210
+ systemctl enable scrapling-mcp
4211
+ systemctl start scrapling-mcp
4212
+ echo "systemd service created and started"
4213
+ else
4214
+ systemctl restart scrapling-mcp
4215
+ echo "systemd service restarted"
4216
+ fi
4217
+ elif command -v launchctl &>/dev/null; then
4218
+ # macOS: create launchd plist
4219
+ PLIST="/Library/LaunchDaemons/com.scrapling.mcp.plist"
4220
+ if [ ! -f "$PLIST" ]; then
4221
+ cat > "$PLIST" << 'PLIST'
4222
+ <?xml version="1.0" encoding="UTF-8"?>
4223
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
4224
+ <plist version="1.0"><dict>
4225
+ <key>Label</key><string>com.scrapling.mcp</string>
4226
+ <key>ProgramArguments</key><array><string>/usr/local/bin/scrapling</string><string>mcp</string><string>--http</string><string>--port</string><string>8931</string></array>
4227
+ <key>RunAtLoad</key><true/>
4228
+ <key>KeepAlive</key><true/>
4229
+ </dict></plist>
4230
+ PLIST
4231
+ launchctl load "$PLIST"
4232
+ echo "launchd service created and loaded"
4233
+ else
4234
+ launchctl unload "$PLIST" 2>/dev/null; launchctl load "$PLIST"
4235
+ echo "launchd service reloaded"
4236
+ fi
4201
4237
  else
4202
- systemctl restart scrapling-mcp
4203
- echo "systemd service restarted"
4238
+ # Fallback: run in background with nohup
4239
+ nohup scrapling mcp --http --port 8931 &>/tmp/scrapling-mcp.log &
4240
+ echo "started in background (no service manager)"
4204
4241
  fi`.trim();
4205
4242
  const r = await manager.exec(target, installScript);
4206
4243
  return okBrief(`Scrapling install on ${target}:\n${r.stdout.trim()}`);
4207
4244
  }
4208
4245
  // --- Action: status ---
4209
4246
  if (action === 'status') {
4210
- const r = await manager.exec(target, `python3 -c "import scrapling; print('version:', scrapling.__version__)" 2>&1; systemctl is-active scrapling-mcp 2>/dev/null || echo "no systemd"; curl -s --connect-timeout 2 http://localhost:8931/ 2>&1 | head -1 || echo "MCP server not reachable"`);
4247
+ const targetOs = remoteNodes().find(n => n.id === target)?.os ?? 'linux';
4248
+ const pyCmd = targetOs === 'windows' ? 'python' : 'python3';
4249
+ const statusScript = targetOs === 'windows'
4250
+ ? `${pyCmd} -c "import scrapling; print('version:', scrapling.__version__)" 2>&1; curl -s --connect-timeout 2 http://localhost:8931/ 2>&1 | head -1`
4251
+ : `${pyCmd} -c "import scrapling; print('version:', scrapling.__version__)" 2>&1; systemctl is-active scrapling-mcp 2>/dev/null || (launchctl list com.scrapling.mcp 2>/dev/null && echo "launchd") || echo "no service manager"; curl -s --connect-timeout 2 http://localhost:8931/ 2>&1 | head -1 || echo "MCP server not reachable"`;
4252
+ const r = await manager.exec(target, statusScript);
4211
4253
  return okBrief(`Scrapling on ${target}:\n${r.stdout.trim()}`);
4212
4254
  }
4213
4255
  // --- Action: scrape ---
@@ -4287,7 +4329,9 @@ print(json.dumps(results))
4287
4329
  `.trim();
4288
4330
  try {
4289
4331
  // Route through VPN if requested, otherwise direct exec via WireGuard mesh
4290
- let execCmd = `python3 -c ${JSON.stringify(script)}`;
4332
+ const targetOs = remoteNodes().find(n => n.id === target)?.os ?? 'linux';
4333
+ const pyCmd = targetOs === 'windows' ? 'python' : 'python3';
4334
+ let execCmd = `${pyCmd} -c ${JSON.stringify(script)}`;
4291
4335
  if (via_vpn)
4292
4336
  execCmd = buildVpnWrappedCmd(via_vpn, execCmd);
4293
4337
  const r = await manager.exec(target, execCmd);