@agentxv2/gateway 0.1.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/.env.example +53 -0
- package/db/migrations/001_init.sql +117 -0
- package/db/migrations/002_agents.sql +20 -0
- package/db/migrations/003_a2a_results.sql +23 -0
- package/deploy/.env.deploy.example +23 -0
- package/deploy/add_swap_build.py +45 -0
- package/deploy/build_and_deploy.py +110 -0
- package/deploy/build_deploy_a2a.py +190 -0
- package/deploy/build_no_lint.py +52 -0
- package/deploy/build_on_fe.py +86 -0
- package/deploy/build_on_gw.py +98 -0
- package/deploy/build_prod.py +54 -0
- package/deploy/check_bal.py +31 -0
- package/deploy/check_code.py +47 -0
- package/deploy/check_deploy.sh +20 -0
- package/deploy/check_docs.py +16 -0
- package/deploy/check_frontend.py +42 -0
- package/deploy/check_frontend2.py +35 -0
- package/deploy/check_pks.py +34 -0
- package/deploy/check_status.py +32 -0
- package/deploy/check_v2.py +8 -0
- package/deploy/clean_install.py +28 -0
- package/deploy/deploy_a2a.py +58 -0
- package/deploy/deploy_a2a.sh +33 -0
- package/deploy/deploy_a2a_bg.sh +40 -0
- package/deploy/deploy_a2a_v2.py +151 -0
- package/deploy/deploy_a2a_v2.sh +36 -0
- package/deploy/deploy_bin.py +64 -0
- package/deploy/deploy_config.py +34 -0
- package/deploy/deploy_final.py +42 -0
- package/deploy/deploy_frontend.py +108 -0
- package/deploy/deploy_mcp.py +108 -0
- package/deploy/deploy_now.py +49 -0
- package/deploy/deploy_push_all.py +128 -0
- package/deploy/deploy_script.py +64 -0
- package/deploy/deploy_sep_a2a.sh +18 -0
- package/deploy/dev_mode.py +51 -0
- package/deploy/diag.py +12 -0
- package/deploy/diff_test.py +22 -0
- package/deploy/final_check.py +33 -0
- package/deploy/final_deploy.py +50 -0
- package/deploy/final_fix.py +54 -0
- package/deploy/final_push.py +114 -0
- package/deploy/find_frontend.py +38 -0
- package/deploy/fix_a2a.py +43 -0
- package/deploy/fix_and_build.py +77 -0
- package/deploy/fix_and_verify.py +56 -0
- package/deploy/fix_build.py +51 -0
- package/deploy/forge_deploy.py +67 -0
- package/deploy/full_push.py +101 -0
- package/deploy/full_push2.py +106 -0
- package/deploy/go_prod.py +59 -0
- package/deploy/gw_deploy.py +133 -0
- package/deploy/gw_final.py +206 -0
- package/deploy/gw_restart.py +28 -0
- package/deploy/gw_status.py +18 -0
- package/deploy/inline_build.py +99 -0
- package/deploy/one_shot.py +84 -0
- package/deploy/ox_deploy.py +32 -0
- package/deploy/pg_setup.py +36 -0
- package/deploy/prod_deploy.py +126 -0
- package/deploy/prod_final.py +140 -0
- package/deploy/prod_go.py +61 -0
- package/deploy/prod_one_shot.py +139 -0
- package/deploy/prod_setup.sh +62 -0
- package/deploy/prod_v2.py +91 -0
- package/deploy/prod_v3.py +103 -0
- package/deploy/push_docs.py +93 -0
- package/deploy/push_mcp.py +66 -0
- package/deploy/push_mcp_doc.py +28 -0
- package/deploy/push_v063.py +80 -0
- package/deploy/push_v2.py +71 -0
- package/deploy/qcheck.py +13 -0
- package/deploy/qcheck2.py +18 -0
- package/deploy/quick_check.py +8 -0
- package/deploy/rebuild.py +47 -0
- package/deploy/rebuild_frontend.py +44 -0
- package/deploy/restart.py +28 -0
- package/deploy/restore_frontend.py +42 -0
- package/deploy/restore_frontend2.py +41 -0
- package/deploy/restore_gateway.py +34 -0
- package/deploy/restore_quick.py +33 -0
- package/deploy/run_bash.py +19 -0
- package/deploy/run_sep.py +20 -0
- package/deploy/sdk_upgrade.py +50 -0
- package/deploy/server_prepare.py +41 -0
- package/deploy/server_setup.py +41 -0
- package/deploy/ssh_check.py +14 -0
- package/deploy/ssh_push.py +24 -0
- package/deploy/start_deploy.py +35 -0
- package/deploy/start_frontend.py +12 -0
- package/deploy/start_v2.py +29 -0
- package/deploy/stat.py +18 -0
- package/deploy/tail_log.py +11 -0
- package/deploy/update_env.py +32 -0
- package/deploy/upload_and_start.py +107 -0
- package/deploy/verify_a2a.py +13 -0
- package/deploy/verify_mcp.py +37 -0
- package/deploy/verify_sdk.py +21 -0
- package/dist/config.d.ts +26 -0
- package/dist/config.js +41 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +149 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/crypto.d.ts +2 -0
- package/dist/lib/crypto.js +43 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/lib/db.d.ts +3 -0
- package/dist/lib/db.js +26 -0
- package/dist/lib/db.js.map +1 -0
- package/dist/lib/ethers-utils.d.ts +60 -0
- package/dist/lib/ethers-utils.js +186 -0
- package/dist/lib/ethers-utils.js.map +1 -0
- package/dist/middleware/adminAuth.d.ts +2 -0
- package/dist/middleware/adminAuth.js +31 -0
- package/dist/middleware/adminAuth.js.map +1 -0
- package/dist/middleware/auth.d.ts +22 -0
- package/dist/middleware/auth.js +192 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +36 -0
- package/dist/middleware/error-handler.js +100 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/rate-limiter.d.ts +5 -0
- package/dist/middleware/rate-limiter.js +107 -0
- package/dist/middleware/rate-limiter.js.map +1 -0
- package/dist/routes/a2a.d.ts +2 -0
- package/dist/routes/a2a.js +84 -0
- package/dist/routes/a2a.js.map +1 -0
- package/dist/routes/admin.d.ts +2 -0
- package/dist/routes/admin.js +180 -0
- package/dist/routes/admin.js.map +1 -0
- package/dist/routes/agents.d.ts +2 -0
- package/dist/routes/agents.js +43 -0
- package/dist/routes/agents.js.map +1 -0
- package/dist/routes/chat.d.ts +2 -0
- package/dist/routes/chat.js +183 -0
- package/dist/routes/chat.js.map +1 -0
- package/dist/routes/history.d.ts +2 -0
- package/dist/routes/history.js +92 -0
- package/dist/routes/history.js.map +1 -0
- package/dist/routes/mcp.d.ts +13 -0
- package/dist/routes/mcp.js +513 -0
- package/dist/routes/mcp.js.map +1 -0
- package/dist/routes/tenant.d.ts +2 -0
- package/dist/routes/tenant.js +154 -0
- package/dist/routes/tenant.js.map +1 -0
- package/dist/services/a2a-worker.d.ts +7 -0
- package/dist/services/a2a-worker.js +406 -0
- package/dist/services/a2a-worker.js.map +1 -0
- package/dist/services/agent-indexer.d.ts +4 -0
- package/dist/services/agent-indexer.js +124 -0
- package/dist/services/agent-indexer.js.map +1 -0
- package/e2e_wallet.js +175 -0
- package/ecosystem.config.js +17 -0
- package/package.json +33 -0
- package/src/config.ts +47 -0
- package/src/index.ts +143 -0
- package/src/lib/crypto.ts +44 -0
- package/src/lib/db.ts +25 -0
- package/src/lib/ethers-utils.ts +229 -0
- package/src/middleware/adminAuth.ts +34 -0
- package/src/middleware/auth.ts +244 -0
- package/src/middleware/error-handler.ts +109 -0
- package/src/middleware/rate-limiter.ts +115 -0
- package/src/routes/a2a.ts +97 -0
- package/src/routes/admin.ts +219 -0
- package/src/routes/agents.ts +52 -0
- package/src/routes/chat.ts +219 -0
- package/src/routes/history.ts +114 -0
- package/src/routes/mcp.ts +567 -0
- package/src/routes/tenant.ts +196 -0
- package/src/services/a2a-worker.ts +486 -0
- package/src/services/agent-indexer.ts +127 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import paramiko, base64, time
|
|
2
|
+
|
|
3
|
+
HOST = '43.156.225.164'
|
|
4
|
+
PWD = 'Asdf1234!'
|
|
5
|
+
|
|
6
|
+
c = paramiko.SSHClient()
|
|
7
|
+
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
8
|
+
c.connect(HOST, username='ubuntu', password=PWD, timeout=30)
|
|
9
|
+
|
|
10
|
+
# Upload fixed page.tsx
|
|
11
|
+
with open(r'c:\Users\apply\Downloads\code\agentx\extracted\Agentx\frontend\app\user\chat\[agentId]\page.tsx', 'r', encoding='utf-8') as f:
|
|
12
|
+
content = f.read()
|
|
13
|
+
b64 = base64.b64encode(content.encode()).decode()
|
|
14
|
+
|
|
15
|
+
stdin, stdout, stderr = c.exec_command(
|
|
16
|
+
f"echo '{b64}' | base64 -d > '/home/ubuntu/agentx-platform/app/user/chat/[agentId]/page.tsx' && wc -c '/home/ubuntu/agentx-platform/app/user/chat/[agentId]/page.tsx'",
|
|
17
|
+
timeout=15
|
|
18
|
+
)
|
|
19
|
+
print(stdout.read().decode().strip())
|
|
20
|
+
|
|
21
|
+
# Install missing dep
|
|
22
|
+
print("\n=== npm install missing ===")
|
|
23
|
+
stdin, stdout, stderr = c.exec_command(
|
|
24
|
+
"cd /home/ubuntu/agentx-platform && npm install --save-dev @react-native-async-storage/async-storage 2>&1 | tail -5",
|
|
25
|
+
timeout=120
|
|
26
|
+
)
|
|
27
|
+
print(stdout.read().decode().strip())
|
|
28
|
+
|
|
29
|
+
# Build
|
|
30
|
+
print("\n=== Build ===")
|
|
31
|
+
stdin, stdout, stderr = c.exec_command(
|
|
32
|
+
"cd /home/ubuntu/agentx-platform && "
|
|
33
|
+
"NODE_OPTIONS='--max-old-space-size=2560' ./node_modules/.bin/next build 2>&1 | tail -15",
|
|
34
|
+
timeout=600
|
|
35
|
+
)
|
|
36
|
+
out = stdout.read().decode()
|
|
37
|
+
err = stderr.read().decode()
|
|
38
|
+
ec = stdout.channel.recv_exit_status()
|
|
39
|
+
|
|
40
|
+
# Check if build succeeded by looking for BUILD_ID
|
|
41
|
+
stdin2, stdout2, stderr2 = c.exec_command(
|
|
42
|
+
"ls /home/ubuntu/agentx-platform/.next/BUILD_ID 2>/dev/null && echo 'BUILD_OK' || echo 'BUILD_FAILED'"
|
|
43
|
+
)
|
|
44
|
+
check = stdout2.read().decode().strip()
|
|
45
|
+
print(out[-500:])
|
|
46
|
+
if err and 'warn' not in err.lower(): print("ERR:", err[-300:])
|
|
47
|
+
print(f"Check: {check}")
|
|
48
|
+
|
|
49
|
+
if 'FAILED' in check:
|
|
50
|
+
# Show full error
|
|
51
|
+
stdin3, stdout3, stderr3 = c.exec_command(
|
|
52
|
+
"cd /home/ubuntu/agentx-platform && "
|
|
53
|
+
"./node_modules/.bin/next build 2>&1 | grep -E 'error|Error|Module not found|Failed' | tail -10",
|
|
54
|
+
timeout=120
|
|
55
|
+
)
|
|
56
|
+
print(stdout3.read().decode())
|
|
57
|
+
c.close()
|
|
58
|
+
exit(1)
|
|
59
|
+
|
|
60
|
+
# Start
|
|
61
|
+
print("\n=== Start ===")
|
|
62
|
+
c.exec_command("fuser -k 3000/tcp 2>/dev/null; sleep 2", timeout=10)
|
|
63
|
+
c.exec_command(
|
|
64
|
+
"cd /home/ubuntu/agentx-platform && "
|
|
65
|
+
"nohup ./node_modules/.bin/next start -p 3000 > /tmp/agentx-run.log 2>&1 & disown",
|
|
66
|
+
timeout=5
|
|
67
|
+
)
|
|
68
|
+
time.sleep(6)
|
|
69
|
+
|
|
70
|
+
stdin4, stdout4, stderr4 = c.exec_command(
|
|
71
|
+
"ss -tlnp | grep 3000 && echo '---' && "
|
|
72
|
+
"curl -sI http://localhost:3000/ 2>&1 | head -3"
|
|
73
|
+
)
|
|
74
|
+
print(stdout4.read().decode())
|
|
75
|
+
|
|
76
|
+
c.close()
|
|
77
|
+
print("\n✅ DONE — http://43.156.225.164:3000")
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import paramiko
|
|
2
|
+
|
|
3
|
+
host = '101.33.109.117'
|
|
4
|
+
user = 'ubuntu'
|
|
5
|
+
password = 'Asdf1234!'
|
|
6
|
+
|
|
7
|
+
client = paramiko.SSHClient()
|
|
8
|
+
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
9
|
+
client.connect(host, username=user, password=password)
|
|
10
|
+
|
|
11
|
+
def run(cmd):
|
|
12
|
+
print(f"> {cmd}")
|
|
13
|
+
stdin, stdout, stderr = client.exec_command(cmd)
|
|
14
|
+
out = stdout.read().decode()
|
|
15
|
+
err = stderr.read().decode()
|
|
16
|
+
stdout.channel.recv_exit_status()
|
|
17
|
+
if out: print(out)
|
|
18
|
+
if err and 'ERR' not in cmd: print("ERR:", err[:300])
|
|
19
|
+
return out, err
|
|
20
|
+
|
|
21
|
+
# Fix: ethers.randomBytes(16) -> crypto.randomBytes(16) in auth.ts
|
|
22
|
+
print("=== Fixing auth.ts ===")
|
|
23
|
+
run("cd ~/agentx-gateway && sed -i \"s/ethers.randomBytes(16)/crypto.randomBytes(16)/g\" src/middleware/auth.ts")
|
|
24
|
+
run("cd ~/agentx-gateway && sed -i \"1i import crypto from 'crypto'\" src/middleware/auth.ts")
|
|
25
|
+
|
|
26
|
+
# Also fix: .toString('hex') for Buffer
|
|
27
|
+
run("cd ~/agentx-gateway && sed -i \"s/crypto.randomBytes(16).toString('hex')/crypto.randomBytes(16).toString('hex')/g\" src/middleware/auth.ts")
|
|
28
|
+
|
|
29
|
+
# Rebuild
|
|
30
|
+
print("\n=== Rebuilding ===")
|
|
31
|
+
run("cd ~/agentx-gateway && ./node_modules/.bin/tsc 2>&1")
|
|
32
|
+
|
|
33
|
+
# Restart
|
|
34
|
+
print("\n=== Restarting PM2 ===")
|
|
35
|
+
run("pm2 restart agentx-gateway 2>&1")
|
|
36
|
+
|
|
37
|
+
# Verify again
|
|
38
|
+
import time
|
|
39
|
+
time.sleep(2)
|
|
40
|
+
print("\n=== Verify ===")
|
|
41
|
+
run("curl -s http://localhost:3090/api/v1/health")
|
|
42
|
+
|
|
43
|
+
# Test auth endpoint
|
|
44
|
+
print("\n=== Test Auth Challenge ===")
|
|
45
|
+
run("curl -s 'http://localhost:3090/api/v1/auth/challenge?address=0x1234567890123456789012345678901234567890'")
|
|
46
|
+
|
|
47
|
+
# Test tenant me (should return 401 without token)
|
|
48
|
+
print("\n=== Test Protected Route ===")
|
|
49
|
+
run("curl -s http://localhost:3090/api/v1/tenant/me")
|
|
50
|
+
|
|
51
|
+
# Also set up UFW to allow port 3090
|
|
52
|
+
print("\n=== Opening firewall port ===")
|
|
53
|
+
run("sudo ufw allow 3090/tcp 2>&1 || echo 'UFW not active'")
|
|
54
|
+
|
|
55
|
+
client.close()
|
|
56
|
+
print("\n=== Done ===")
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import paramiko
|
|
2
|
+
|
|
3
|
+
host = '101.33.109.117'
|
|
4
|
+
user = 'ubuntu'
|
|
5
|
+
password = 'Asdf1234!'
|
|
6
|
+
|
|
7
|
+
client = paramiko.SSHClient()
|
|
8
|
+
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
9
|
+
client.connect(host, username=user, password=password)
|
|
10
|
+
|
|
11
|
+
def run(cmd):
|
|
12
|
+
print(f"> {cmd}")
|
|
13
|
+
stdin, stdout, stderr = client.exec_command(cmd)
|
|
14
|
+
out = stdout.read().decode()
|
|
15
|
+
err = stderr.read().decode()
|
|
16
|
+
stdout.channel.recv_exit_status()
|
|
17
|
+
if out: print(out)
|
|
18
|
+
if err: print("ERR:", err[:500])
|
|
19
|
+
return out, err
|
|
20
|
+
|
|
21
|
+
# Fix: install devDependencies for TypeScript compilation
|
|
22
|
+
print("=== Installing all dependencies (including dev) ===")
|
|
23
|
+
run("cd ~/agentx-gateway && npm install 2>&1")
|
|
24
|
+
|
|
25
|
+
# Build
|
|
26
|
+
print("\n=== Building TypeScript ===")
|
|
27
|
+
run("cd ~/agentx-gateway && ./node_modules/.bin/tsc 2>&1")
|
|
28
|
+
|
|
29
|
+
# Verify build output
|
|
30
|
+
print("\n=== Checking build output ===")
|
|
31
|
+
run("ls -la ~/agentx-gateway/dist/ 2>&1")
|
|
32
|
+
|
|
33
|
+
# Kill existing PM2 and restart
|
|
34
|
+
print("\n=== Restarting PM2 ===")
|
|
35
|
+
run("pm2 delete all 2>&1")
|
|
36
|
+
run("cd ~/agentx-gateway && pm2 start ecosystem.config.js 2>&1")
|
|
37
|
+
run("pm2 save --force 2>&1")
|
|
38
|
+
|
|
39
|
+
# Verify
|
|
40
|
+
print("\n=== Verifying Gateway ===")
|
|
41
|
+
import time
|
|
42
|
+
time.sleep(2)
|
|
43
|
+
run("curl -s http://localhost:3090/api/v1/health 2>&1")
|
|
44
|
+
run("pm2 status 2>&1")
|
|
45
|
+
|
|
46
|
+
# Also set PM2 to auto-start on boot
|
|
47
|
+
print("\n=== PM2 startup ===")
|
|
48
|
+
run("pm2 startup 2>&1")
|
|
49
|
+
|
|
50
|
+
client.close()
|
|
51
|
+
print("\n=== Done ===")
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import paramiko
|
|
2
|
+
import subprocess, sys
|
|
3
|
+
|
|
4
|
+
pk = '0x872c3190b82d17b29bb046c9c55a7f7390c7f74bd6d592ba8d211f20f896f28e'
|
|
5
|
+
sep_ir = '0xe94ad380d3F8d08a7590eda0C84f354a93F96e5F'
|
|
6
|
+
ox_ir = '0xbf5F9db266c8c97E3334466C88597Eb758AfE212'
|
|
7
|
+
sep_rpc = 'https://ethereum-sepolia-rpc.publicnode.com'
|
|
8
|
+
ox_rpc = 'http://43.156.99.215:18545'
|
|
9
|
+
|
|
10
|
+
c = paramiko.SSHClient()
|
|
11
|
+
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
12
|
+
c.connect('43.156.78.59', username='ubuntu', password='Asdf1234!', timeout=30)
|
|
13
|
+
|
|
14
|
+
def run(cmd):
|
|
15
|
+
print(f"> {cmd[:130]}")
|
|
16
|
+
stdin, stdout, stderr = c.exec_command(cmd, timeout=600)
|
|
17
|
+
out = stdout.read().decode()
|
|
18
|
+
err = stderr.read().decode()
|
|
19
|
+
ec = stdout.channel.recv_exit_status()
|
|
20
|
+
if out: print(out[-400:])
|
|
21
|
+
if err: print("STDERR:", err[-400:])
|
|
22
|
+
return ec, out, err
|
|
23
|
+
|
|
24
|
+
# Ensure symlink exists
|
|
25
|
+
run("cd /tmp/a2a_build/src && ln -sf erc8004-interfaces interfaces && echo LINK_OK")
|
|
26
|
+
|
|
27
|
+
# Deploy Sepolia
|
|
28
|
+
print("\n=== SEPOLIA ===")
|
|
29
|
+
ec, out, err = run(
|
|
30
|
+
f"export PATH=$HOME/.foundry/bin:$PATH && cd /tmp/a2a_build && "
|
|
31
|
+
f"forge create src/erc8004-extensions/A2AProtocolRegistry.sol:A2AProtocolRegistry "
|
|
32
|
+
f"--rpc-url {sep_rpc} --private-key {pk} --legacy "
|
|
33
|
+
f'--constructor-args $(cast abi-encode "constructor(address)" {sep_ir}) '
|
|
34
|
+
f"2>&1"
|
|
35
|
+
)
|
|
36
|
+
sep_addr = ""
|
|
37
|
+
for line in (out + err).split('\n'):
|
|
38
|
+
if 'Deployed to' in line:
|
|
39
|
+
sep_addr = line.split(':')[-1].strip()
|
|
40
|
+
print(f"\n*** SEPOLIA A2A: {sep_addr}")
|
|
41
|
+
|
|
42
|
+
# Deploy OxaChain
|
|
43
|
+
print("\n=== OXACHAIN L1 ===")
|
|
44
|
+
ec, out, err = run(
|
|
45
|
+
f"export PATH=$HOME/.foundry/bin:$PATH && cd /tmp/a2a_build && "
|
|
46
|
+
f"forge create src/erc8004-extensions/A2AProtocolRegistry.sol:A2AProtocolRegistry "
|
|
47
|
+
f"--rpc-url {ox_rpc} --private-key {pk} --legacy "
|
|
48
|
+
f'--constructor-args $(cast abi-encode "constructor(address)" {ox_ir}) '
|
|
49
|
+
f"2>&1"
|
|
50
|
+
)
|
|
51
|
+
ox_addr = ""
|
|
52
|
+
for line in (out + err).split('\n'):
|
|
53
|
+
if 'Deployed to' in line:
|
|
54
|
+
ox_addr = line.split(':')[-1].strip()
|
|
55
|
+
print(f"\n*** OXACHAIN A2A: {ox_addr}")
|
|
56
|
+
|
|
57
|
+
c.close()
|
|
58
|
+
|
|
59
|
+
print("\n============================================")
|
|
60
|
+
print(f"SEPOLIA_A2A={sep_addr}")
|
|
61
|
+
print(f"OXACHAIN_A2A={ox_addr}")
|
|
62
|
+
print("============================================")
|
|
63
|
+
|
|
64
|
+
if sep_addr:
|
|
65
|
+
with open(r'c:\Users\apply\Downloads\code\agentx\extracted\Agentx\gateway\deploy\a2a_addresses.txt', 'w') as f:
|
|
66
|
+
f.write(f"SEPOLIA_A2A={sep_addr}\n")
|
|
67
|
+
f.write(f"OXACHAIN_A2A={ox_addr}\n")
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
import paramiko, tarfile, os, base64
|
|
3
|
+
|
|
4
|
+
HOST = '43.156.78.59'
|
|
5
|
+
PWD = 'Asdf1234!'
|
|
6
|
+
ROOT = r'c:\Users\apply\Downloads\code\agentx\extracted\Agentx'
|
|
7
|
+
TARPATH = r'c:\Users\apply\Downloads\code\agentx_full.tar.gz'
|
|
8
|
+
|
|
9
|
+
EXCLUDE = {'node_modules', '.next', '.git', 'dist', 'archive', '__pycache__', '.turbo'}
|
|
10
|
+
|
|
11
|
+
# 1. Create tar
|
|
12
|
+
print("=== Creating full-source tar ===")
|
|
13
|
+
count = 0
|
|
14
|
+
with tarfile.open(TARPATH, 'w:gz') as tar:
|
|
15
|
+
for root, dirs, files in os.walk(ROOT):
|
|
16
|
+
dirs[:] = [d for d in dirs if d not in EXCLUDE]
|
|
17
|
+
for f in files:
|
|
18
|
+
if any(s in f for s in ['.tsbuildinfo', 'pnpm-lock.yaml', '.tar.gz', '.tgz']):
|
|
19
|
+
continue
|
|
20
|
+
full = os.path.join(root, f)
|
|
21
|
+
arc = os.path.relpath(full, ROOT).replace('\\', '/')
|
|
22
|
+
tar.add(full, arcname=arc)
|
|
23
|
+
count += 1
|
|
24
|
+
|
|
25
|
+
size_mb = os.path.getsize(TARPATH) / (1024*1024)
|
|
26
|
+
print(f"{count} files, {size_mb:.1f} MB")
|
|
27
|
+
|
|
28
|
+
# 2. Upload
|
|
29
|
+
print("\n=== Uploading ===")
|
|
30
|
+
t = paramiko.Transport((HOST, 22))
|
|
31
|
+
t.connect(username='ubuntu', password=PWD)
|
|
32
|
+
s = paramiko.SFTPClient.from_transport(t)
|
|
33
|
+
s.put(TARPATH, '/tmp/agentx_full.tar.gz')
|
|
34
|
+
s.close()
|
|
35
|
+
t.close()
|
|
36
|
+
print("Uploaded")
|
|
37
|
+
|
|
38
|
+
# 3. Git clone + overwrite + push + tag
|
|
39
|
+
push_script = r'''#!/bin/bash
|
|
40
|
+
set -e
|
|
41
|
+
cd /tmp
|
|
42
|
+
rm -rf agentx-full-push
|
|
43
|
+
git clone git@github.com:sftgroup/Agentx.git agentx-full-push 2>&1 | tail -2
|
|
44
|
+
|
|
45
|
+
cd agentx-full-push
|
|
46
|
+
|
|
47
|
+
# Remove everything except .git
|
|
48
|
+
find . -mindepth 1 -maxdepth 1 -not -name '.git' -exec rm -rf {} \; 2>/dev/null || true
|
|
49
|
+
|
|
50
|
+
# Extract our code
|
|
51
|
+
tar xzf /tmp/agentx_full.tar.gz
|
|
52
|
+
echo "Extracted $(find . -type f -not -path './.git/*' | wc -l) files"
|
|
53
|
+
|
|
54
|
+
# Show stats
|
|
55
|
+
git add -A
|
|
56
|
+
echo "=== STATS ==="
|
|
57
|
+
git diff --cached --stat | tail -20
|
|
58
|
+
|
|
59
|
+
# Commit
|
|
60
|
+
git commit -m "release: v0.6.2 — full-stack production (164), A2A v2 dual-chain, Gateway migration, MCP setup guide, AgentLoop ReAct engine
|
|
61
|
+
|
|
62
|
+
- Smart contracts: A2AProtocolRegistry v2 with getUserTasks (Sepolia + OxaChain L1)
|
|
63
|
+
- SDK: @agentxv2/sdk@0.6.2 (13 modules, CJS/ESM/DTS)
|
|
64
|
+
- Frontend: Next.js 16.2 Turbopack standalone (production: 43.156.225.164:3000)
|
|
65
|
+
- Gateway: Express TypeScript multi-tenant LLM proxy (production: 43.156.225.164:3090)
|
|
66
|
+
- PostgreSQL: 6-table schema with seed data
|
|
67
|
+
- Docs: README, INTEGRATION, DEPLOYMENT, MCP_SETUP, PROGRESS (all updated)
|
|
68
|
+
- Bug fixes: A2A page wrong contract, getUserTasks missing, PaymentGateway deprecated
|
|
69
|
+
" 2>&1
|
|
70
|
+
|
|
71
|
+
# Push
|
|
72
|
+
git push origin main 2>&1
|
|
73
|
+
echo "=== PUSH OK ==="
|
|
74
|
+
|
|
75
|
+
# Tag
|
|
76
|
+
git tag -a v0.6.2 -m "v0.6.2 — Full-stack production release on 43.156.225.164
|
|
77
|
+
- A2AProtocolRegistry v2 (Sepolia: 0x309C...7e9cB, OxaChain: 0xDF29...112B)
|
|
78
|
+
- Gateway migrated to 164 (Express + PostgreSQL)
|
|
79
|
+
- MCP remote tool setup guide
|
|
80
|
+
- AgentLoop ReAct engine
|
|
81
|
+
- Dual-chain support (Sepolia 11155111 + OxaChain L1 19505)
|
|
82
|
+
"
|
|
83
|
+
|
|
84
|
+
git push origin v0.6.2 2>&1
|
|
85
|
+
echo "=== TAG PUSHED ==="
|
|
86
|
+
'''
|
|
87
|
+
|
|
88
|
+
b64 = base64.b64encode(push_script.encode()).decode()
|
|
89
|
+
c = paramiko.SSHClient()
|
|
90
|
+
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
91
|
+
c.connect(HOST, username='ubuntu', password=PWD, timeout=30)
|
|
92
|
+
|
|
93
|
+
stdin, stdout, stderr = c.exec_command(
|
|
94
|
+
f"echo '{b64}' | base64 -d > /tmp/full_push.sh && chmod +x /tmp/full_push.sh && bash /tmp/full_push.sh 2>&1"
|
|
95
|
+
)
|
|
96
|
+
out = stdout.read().decode()
|
|
97
|
+
err = stderr.read().decode()
|
|
98
|
+
print("\n=== RESULT ===")
|
|
99
|
+
print(out)
|
|
100
|
+
if err: print("E:", err[-500:])
|
|
101
|
+
c.close()
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
import paramiko, tarfile, os, base64
|
|
3
|
+
|
|
4
|
+
HOST = '43.156.78.59'
|
|
5
|
+
PWD = 'Asdf1234!'
|
|
6
|
+
ROOT = r'c:\Users\apply\Downloads\code\agentx\extracted\Agentx'
|
|
7
|
+
TARPATH = r'c:\Users\apply\Downloads\code\agentx_full.tar.gz'
|
|
8
|
+
|
|
9
|
+
EXCLUDE = {'node_modules', '.next', '.git', 'dist', 'archive', '__pycache__', '.turbo'}
|
|
10
|
+
|
|
11
|
+
# Files containing secrets (passwords, tokens, private keys) — exclude
|
|
12
|
+
SECRET_FILES = {
|
|
13
|
+
'git_push.py', 'restore_gateway.py', 'restore_quick.py', 'restore_frontend.py',
|
|
14
|
+
'restore_frontend2.py', 'server_prepare.py', 'server_setup.py', 'upload_and_start.py',
|
|
15
|
+
'start_deploy.py', 'start_frontend.py', 'start_v2.py', 'deploy_frontend.py',
|
|
16
|
+
'build_on_gw.py', 'build_on_fe.py', 'one_shot.py', 'final_check.py',
|
|
17
|
+
'final_deploy.py', 'final_fix.py', 'fix_and_verify.py', 'fix_build.py',
|
|
18
|
+
'fix_frontend.py', 'find_frontend.py', 'inline_build.py', 'rebuild_frontend.py',
|
|
19
|
+
'deploy_script.py', 'deploy_final.py', 'deploy_now.py', 'dev_mode.py',
|
|
20
|
+
'check_frontend.py', 'check_frontend2.py'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
print("=== Creating full-source tar ===")
|
|
24
|
+
count = 0
|
|
25
|
+
with tarfile.open(TARPATH, 'w:gz') as tar:
|
|
26
|
+
for root, dirs, files in os.walk(ROOT):
|
|
27
|
+
dirs[:] = [d for d in dirs if d not in EXCLUDE]
|
|
28
|
+
for f in files:
|
|
29
|
+
if any(s in f for s in ['.tsbuildinfo', 'pnpm-lock.yaml', '.tar.gz', '.tgz']):
|
|
30
|
+
continue
|
|
31
|
+
if f in SECRET_FILES:
|
|
32
|
+
continue
|
|
33
|
+
full = os.path.join(root, f)
|
|
34
|
+
arc = os.path.relpath(full, ROOT).replace('\\', '/')
|
|
35
|
+
tar.add(full, arcname=arc)
|
|
36
|
+
count += 1
|
|
37
|
+
|
|
38
|
+
size_mb = os.path.getsize(TARPATH) / (1024*1024)
|
|
39
|
+
print(f"{count} files, {size_mb:.1f} MB")
|
|
40
|
+
|
|
41
|
+
# Upload
|
|
42
|
+
print("\n=== Uploading ===")
|
|
43
|
+
t = paramiko.Transport((HOST, 22))
|
|
44
|
+
t.connect(username='ubuntu', password=PWD)
|
|
45
|
+
s = paramiko.SFTPClient.from_transport(t)
|
|
46
|
+
s.put(TARPATH, '/tmp/agentx_full.tar.gz')
|
|
47
|
+
s.close()
|
|
48
|
+
t.close()
|
|
49
|
+
print("Uploaded")
|
|
50
|
+
|
|
51
|
+
# Push + tag
|
|
52
|
+
push_script = r'''#!/bin/bash
|
|
53
|
+
set -e
|
|
54
|
+
cd /tmp
|
|
55
|
+
rm -rf agentx-full-push
|
|
56
|
+
git clone git@github.com:sftgroup/Agentx.git agentx-full-push
|
|
57
|
+
cd agentx-full-push
|
|
58
|
+
find . -mindepth 1 -maxdepth 1 -not -name '.git' -exec rm -rf {} \; 2>/dev/null || true
|
|
59
|
+
tar xzf /tmp/agentx_full.tar.gz
|
|
60
|
+
echo "Files: $(find . -type f -not -path './.git/*' | wc -l)"
|
|
61
|
+
git add -A
|
|
62
|
+
echo "=== STATS ==="
|
|
63
|
+
git diff --cached --stat --stat=120 | tail -25
|
|
64
|
+
git commit -m "release: v0.6.2 — full-stack production (164), A2A v2 dual-chain, Gateway, AgentLoop, MCP
|
|
65
|
+
|
|
66
|
+
Core changes:
|
|
67
|
+
- A2AProtocolRegistry v2 with getUserTasks(address) (Sepolia + OxaChain L1)
|
|
68
|
+
- SDK @agentxv2/sdk@0.6.2 (13 modules, dual-chain A2A addresses)
|
|
69
|
+
- Gateway Express TypeScript (EIP-191 auth, dual-mode LLM proxy, 3-layer rate limit)
|
|
70
|
+
- PostgreSQL 6-table schema with seed data
|
|
71
|
+
- Frontend Next.js 16.2 Turbopack (A2A page fix, AgentLoop chat, GatewayProvider)
|
|
72
|
+
- Docs: README, INTEGRATION, DEPLOYMENT, MCP_SETUP, PROGRESS
|
|
73
|
+
- Bug fixes: A2A wrong contract, missing getUserTasks, deprecated PaymentGateway
|
|
74
|
+
|
|
75
|
+
Production: 43.156.225.164 (Frontend :3000, Gateway :3090, PG :5432)
|
|
76
|
+
" 2>&1
|
|
77
|
+
|
|
78
|
+
git push origin main 2>&1
|
|
79
|
+
echo "=== PUSH OK ==="
|
|
80
|
+
|
|
81
|
+
git tag -a v0.6.2 -m "v0.6.2 — Full-stack production release
|
|
82
|
+
- A2AProtocolRegistry v2: Sepolia 0x309C7447d89f3087A9924BB686d88df020F7e9cB, OxaChain 0xDF2939EFafEe6439eB2226DbEd07AD6F5Ae2112B
|
|
83
|
+
- SDK @agentxv2/sdk@0.6.2
|
|
84
|
+
- Gateway on 43.156.225.164:3090
|
|
85
|
+
- Frontend on 43.156.225.164:3000
|
|
86
|
+
- MCP remote tool setup guide
|
|
87
|
+
" 2>&1
|
|
88
|
+
|
|
89
|
+
git push origin v0.6.2 2>&1
|
|
90
|
+
echo "=== TAG PUSHED ==="
|
|
91
|
+
'''
|
|
92
|
+
|
|
93
|
+
b64 = base64.b64encode(push_script.encode()).decode()
|
|
94
|
+
c = paramiko.SSHClient()
|
|
95
|
+
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
96
|
+
c.connect(HOST, username='ubuntu', password=PWD, timeout=30)
|
|
97
|
+
|
|
98
|
+
stdin, stdout, stderr = c.exec_command(
|
|
99
|
+
f"echo '{b64}' | base64 -d > /tmp/full_push2.sh && chmod +x /tmp/full_push2.sh && bash /tmp/full_push2.sh 2>&1"
|
|
100
|
+
)
|
|
101
|
+
out = stdout.read().decode()
|
|
102
|
+
err = stderr.read().decode()
|
|
103
|
+
print("\n=== RESULT ===")
|
|
104
|
+
print(out)
|
|
105
|
+
if err: print("E:", err[-500:])
|
|
106
|
+
c.close()
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import paramiko, base64, time
|
|
2
|
+
|
|
3
|
+
HOST = '43.156.225.164'
|
|
4
|
+
PWD = 'Asdf1234!'
|
|
5
|
+
|
|
6
|
+
c = paramiko.SSHClient()
|
|
7
|
+
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
8
|
+
c.connect(HOST, username='ubuntu', password=PWD, timeout=30)
|
|
9
|
+
|
|
10
|
+
# Upload fixed next.config.js
|
|
11
|
+
with open(r'c:\Users\apply\Downloads\code\agentx\extracted\Agentx\frontend\next.config.js', 'r') as f:
|
|
12
|
+
content = f.read()
|
|
13
|
+
b64 = base64.b64encode(content.encode()).decode()
|
|
14
|
+
stdin, stdout, stderr = c.exec_command(
|
|
15
|
+
f"echo '{b64}' | base64 -d > /home/ubuntu/agentx-platform/next.config.js && echo 'ok'"
|
|
16
|
+
)
|
|
17
|
+
print(stdout.read().decode().strip())
|
|
18
|
+
|
|
19
|
+
# Build
|
|
20
|
+
print("\n=== Build ===")
|
|
21
|
+
stdin, stdout, stderr = c.exec_command(
|
|
22
|
+
"cd /home/ubuntu/agentx-platform && "
|
|
23
|
+
"NODE_OPTIONS='--max-old-space-size=2560' ./node_modules/.bin/next build 2>&1 | tail -20",
|
|
24
|
+
timeout=600
|
|
25
|
+
)
|
|
26
|
+
out = stdout.read().decode()
|
|
27
|
+
err = stderr.read().decode()
|
|
28
|
+
print(out)
|
|
29
|
+
if err: print("E:", err[-300:])
|
|
30
|
+
|
|
31
|
+
# Check
|
|
32
|
+
stdin2, stdout2, stderr2 = c.exec_command(
|
|
33
|
+
"ls /home/ubuntu/agentx-platform/.next/BUILD_ID 2>/dev/null && echo BUILD_OK || echo FAILED"
|
|
34
|
+
)
|
|
35
|
+
check = stdout2.read().decode().strip()
|
|
36
|
+
print(f"Result: {check}")
|
|
37
|
+
|
|
38
|
+
if 'FAILED' in check:
|
|
39
|
+
print("BUILD FAILED!")
|
|
40
|
+
c.close()
|
|
41
|
+
exit(1)
|
|
42
|
+
|
|
43
|
+
# Start
|
|
44
|
+
print("\n=== Start ===")
|
|
45
|
+
c.exec_command("fuser -k 3000/tcp 2>/dev/null; sleep 2", timeout=10)
|
|
46
|
+
channel = c.get_transport().open_session()
|
|
47
|
+
channel.exec_command(
|
|
48
|
+
"cd /home/ubuntu/agentx-platform && "
|
|
49
|
+
"nohup ./node_modules/.bin/next start -p 3000 > /tmp/agentx-run.log 2>&1 & disown"
|
|
50
|
+
)
|
|
51
|
+
time.sleep(6)
|
|
52
|
+
|
|
53
|
+
stdin3, stdout3, stderr3 = c.exec_command(
|
|
54
|
+
"ss -tlnp | grep 3000 && echo '---' && curl -sI http://localhost:3000/ 2>&1 | head -5"
|
|
55
|
+
)
|
|
56
|
+
print(stdout3.read().decode())
|
|
57
|
+
|
|
58
|
+
c.close()
|
|
59
|
+
print("\n✅ http://43.156.225.164:3000")
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import paramiko
|
|
2
|
+
import tarfile
|
|
3
|
+
import os
|
|
4
|
+
import base64
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
HOST = '43.156.225.164'
|
|
8
|
+
PWD = 'Asdf1234!'
|
|
9
|
+
PORT = '3090'
|
|
10
|
+
APP = '/home/ubuntu/agentx-gateway'
|
|
11
|
+
|
|
12
|
+
# 1. Create tar of gateway source
|
|
13
|
+
local = r'c:\Users\apply\Downloads\code\agentx\extracted\Agentx\gateway'
|
|
14
|
+
tarpath = r'c:\Users\apply\Downloads\code\agentx_gw.tar.gz'
|
|
15
|
+
|
|
16
|
+
print("=== Tar ===")
|
|
17
|
+
with tarfile.open(tarpath, 'w:gz') as tar:
|
|
18
|
+
for root, dirs, files in os.walk(local):
|
|
19
|
+
dirs[:] = [d for d in dirs if d not in ('node_modules','dist','.git')]
|
|
20
|
+
for f in files:
|
|
21
|
+
if f.endswith('.tar.gz'): continue
|
|
22
|
+
full = os.path.join(root, f)
|
|
23
|
+
arc = os.path.relpath(full, local).replace('\\', '/')
|
|
24
|
+
tar.add(full, arcname=arc)
|
|
25
|
+
print(f"{os.path.getsize(tarpath)//1024} KB")
|
|
26
|
+
|
|
27
|
+
# 2. Upload
|
|
28
|
+
print("Uploading...")
|
|
29
|
+
t = paramiko.Transport((HOST, 22))
|
|
30
|
+
t.connect(username='ubuntu', password=PWD)
|
|
31
|
+
s = paramiko.SFTPClient.from_transport(t)
|
|
32
|
+
s.put(tarpath, '/tmp/agentx_gw.tar.gz')
|
|
33
|
+
s.close()
|
|
34
|
+
t.close()
|
|
35
|
+
|
|
36
|
+
# 3. Extract + install + build + start
|
|
37
|
+
c = paramiko.SSHClient()
|
|
38
|
+
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
39
|
+
c.connect(HOST, username='ubuntu', password=PWD, timeout=30)
|
|
40
|
+
|
|
41
|
+
# Extract
|
|
42
|
+
stdin, stdout, stderr = c.exec_command(
|
|
43
|
+
f"rm -rf {APP} && mkdir -p {APP} && cd {APP} && tar xzf /tmp/agentx_gw.tar.gz && ls src/index.ts && echo 'OK'",
|
|
44
|
+
timeout=15
|
|
45
|
+
)
|
|
46
|
+
print(stdout.read().decode().strip())
|
|
47
|
+
|
|
48
|
+
# Read gateway .env.example from local
|
|
49
|
+
try:
|
|
50
|
+
with open(local + r'\.env.example', 'r') as f:
|
|
51
|
+
env = f.read()
|
|
52
|
+
except:
|
|
53
|
+
env = ''
|
|
54
|
+
with open(local + r'\.env', 'r') as f:
|
|
55
|
+
env = f.read()
|
|
56
|
+
|
|
57
|
+
# Write .env with PG on localhost
|
|
58
|
+
env_lines = []
|
|
59
|
+
for line in env.split('\n'):
|
|
60
|
+
if line.startswith('DATABASE_URL='):
|
|
61
|
+
env_lines.append('DATABASE_URL=postgresql://agentx:AgentX2024!Gateway@localhost:5432/agentx_gateway')
|
|
62
|
+
elif line.startswith('PG'):
|
|
63
|
+
continue
|
|
64
|
+
else:
|
|
65
|
+
env_lines.append(line)
|
|
66
|
+
# Make sure critical lines exist
|
|
67
|
+
new_env = '\n'.join(env_lines)
|
|
68
|
+
if 'DATABASE_URL' not in new_env:
|
|
69
|
+
new_env += '\nDATABASE_URL=postgresql://agentx:AgentX2024!Gateway@localhost:5432/agentx_gateway'
|
|
70
|
+
if 'PORT=' not in new_env:
|
|
71
|
+
new_env += f'\nPORT={PORT}'
|
|
72
|
+
if 'JWT_SECRET' not in new_env:
|
|
73
|
+
new_env += '\nJWT_SECRET=agentx-prod-jwt-secret-key-2026'
|
|
74
|
+
|
|
75
|
+
b64 = base64.b64encode(new_env.encode()).decode()
|
|
76
|
+
stdin, stdout, stderr = c.exec_command(f"echo '{b64}' | base64 -d > {APP}/.env && echo 'env OK'")
|
|
77
|
+
print(stdout.read().decode().strip())
|
|
78
|
+
|
|
79
|
+
# Check if tsx is available, install deps
|
|
80
|
+
print("\n=== npm install ===")
|
|
81
|
+
stdin, stdout, stderr = c.exec_command(
|
|
82
|
+
f"cd {APP} && npm install 2>&1 | tail -8",
|
|
83
|
+
timeout=600
|
|
84
|
+
)
|
|
85
|
+
out = stdout.read().decode()
|
|
86
|
+
err = stderr.read().decode()
|
|
87
|
+
print(out)
|
|
88
|
+
if err: print("E:", err[-300:])
|
|
89
|
+
|
|
90
|
+
# Build TypeScript
|
|
91
|
+
print("\n=== tsc build ===")
|
|
92
|
+
stdin, stdout, stderr = c.exec_command(
|
|
93
|
+
f"cd {APP} && ./node_modules/.bin/tsc 2>&1 | tail -10; echo 'EXIT='$?",
|
|
94
|
+
timeout=120
|
|
95
|
+
)
|
|
96
|
+
out = stdout.read().decode()
|
|
97
|
+
print(out)
|
|
98
|
+
|
|
99
|
+
# Check if dist exists
|
|
100
|
+
stdin, stdout, stderr = c.exec_command(f"ls {APP}/dist/index.js 2>/dev/null && echo BUILD_OK || echo BUILD_FAILED")
|
|
101
|
+
check = stdout.read().decode().strip()
|
|
102
|
+
print(f"Build: {check}")
|
|
103
|
+
|
|
104
|
+
if 'FAILED' in check:
|
|
105
|
+
stdin, stdout, stderr = c.exec_command(f"cat {APP}/package.json")
|
|
106
|
+
print(stdout.read().decode()[:500])
|
|
107
|
+
# Try with tsx instead of tsc
|
|
108
|
+
print("Trying tsx...")
|
|
109
|
+
stdin, stdout, stderr = c.exec_command(f"cd {APP} && npm install tsx typescript --save-dev 2>&1 | tail -3", timeout=60)
|
|
110
|
+
print(stdout.read().decode())
|
|
111
|
+
stdin, stdout, stderr = c.exec_command(f"cd {APP} && ./node_modules/.bin/tsc --noEmit 2>&1 | tail -5; ls {APP}/dist/index.js 2>/dev/null || echo NO_DIST", timeout=60)
|
|
112
|
+
print(stdout.read().decode())
|
|
113
|
+
|
|
114
|
+
# Kill old + start
|
|
115
|
+
print(f"\n=== Start on {PORT} ===")
|
|
116
|
+
c.exec_command(f"fuser -k {PORT}/tcp 2>/dev/null; sleep 2", timeout=10)
|
|
117
|
+
c.exec_command(
|
|
118
|
+
f"cd {APP} && nohup npx tsx src/index.ts > /tmp/gw.log 2>&1 & disown",
|
|
119
|
+
timeout=5
|
|
120
|
+
)
|
|
121
|
+
time.sleep(4)
|
|
122
|
+
|
|
123
|
+
stdin, stdout, stderr = c.exec_command(f"ss -tlnp | grep {PORT} && echo '---' && curl -s http://localhost:{PORT}/api/v1/health 2>&1")
|
|
124
|
+
out = stdout.read().decode()
|
|
125
|
+
print(out)
|
|
126
|
+
if 'OK' in out or 'ok' in out.lower() or 'health' in out.lower():
|
|
127
|
+
print("\n✅ Gateway running!")
|
|
128
|
+
else:
|
|
129
|
+
# Check logs
|
|
130
|
+
stdin, stdout, stderr = c.exec_command("tail -20 /tmp/gw.log")
|
|
131
|
+
print("Log:", stdout.read().decode()[:500])
|
|
132
|
+
|
|
133
|
+
c.close()
|