yakmesh 1.3.1 → 1.4.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.
@@ -0,0 +1,193 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Start YAKMESH Self-Contained Node
4
+
5
+ .DESCRIPTION
6
+ Starts the complete Yakmesh stack using bundled binaries:
7
+ - Node.js (bundled)
8
+ - Caddy web server (bundled)
9
+ - PHP FastCGI (bundled)
10
+
11
+ No external dependencies required.
12
+ #>
13
+
14
+ $ErrorActionPreference = "Stop"
15
+ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
16
+ Set-Location $ScriptDir
17
+
18
+ Write-Host ""
19
+ Write-Host " =====================================" -ForegroundColor Cyan
20
+ Write-Host " YAKMESH SELF-CONTAINED" -ForegroundColor Cyan
21
+ Write-Host " Complete Stack - All Bundled" -ForegroundColor Cyan
22
+ Write-Host " =====================================" -ForegroundColor Cyan
23
+ Write-Host ""
24
+
25
+ # Paths to bundled binaries
26
+ $nodeBin = Join-Path $ScriptDir "bin\node\node.exe"
27
+ $caddyBin = Join-Path $ScriptDir "bin\caddy.exe"
28
+ $phpBin = Join-Path $ScriptDir "bin\php\php-cgi.exe"
29
+ $phpIni = Join-Path $ScriptDir "bin\php\php.ini"
30
+
31
+ # Verify bundled binaries exist
32
+ $missing = @()
33
+ if (-not (Test-Path $nodeBin)) { $missing += "Node.js (bin/node/node.exe)" }
34
+ if (-not (Test-Path $caddyBin)) { $missing += "Caddy (bin/caddy.exe)" }
35
+ if (-not (Test-Path $phpBin)) { $missing += "PHP (bin/php/php-cgi.exe)" }
36
+
37
+ if ($missing.Count -gt 0) {
38
+ Write-Host "[ERROR] Missing bundled binaries:" -ForegroundColor Red
39
+ $missing | ForEach-Object { Write-Host " - $_" -ForegroundColor Red }
40
+ Write-Host ""
41
+ Write-Host "This is a self-contained package. Binaries should be included." -ForegroundColor Yellow
42
+ Write-Host "Please re-download the full package from yakmesh.dev" -ForegroundColor Yellow
43
+ exit 1
44
+ }
45
+
46
+ # Show versions
47
+ $nodeVersion = & $nodeBin --version
48
+ Write-Host "[OK] Node.js $nodeVersion (bundled)" -ForegroundColor Green
49
+
50
+ $phpVersion = & $phpBin -v 2>$null | Select-Object -First 1
51
+ Write-Host "[OK] PHP $($phpVersion -replace 'PHP (\d+\.\d+\.\d+).*','$1') (bundled)" -ForegroundColor Green
52
+
53
+ $caddyVersion = & $caddyBin version 2>$null
54
+ Write-Host "[OK] Caddy $caddyVersion (bundled)" -ForegroundColor Green
55
+
56
+ # Create directories
57
+ @("htdocs", "data", "data\content", "logs") | ForEach-Object {
58
+ $dir = Join-Path $ScriptDir $_
59
+ if (-not (Test-Path $dir)) {
60
+ New-Item -ItemType Directory -Path $dir -Force | Out-Null
61
+ }
62
+ }
63
+
64
+ # Create default index.html if not exists
65
+ $indexPath = Join-Path $ScriptDir "htdocs\index.html"
66
+ if (-not (Test-Path $indexPath)) {
67
+ @"
68
+ <!DOCTYPE html>
69
+ <html>
70
+ <head>
71
+ <title>YAKMESH Node</title>
72
+ <style>
73
+ body { font-family: system-ui; max-width: 800px; margin: 50px auto; padding: 20px; background: #f8f9fa; }
74
+ h1 { color: #2d5016; }
75
+ code { background: #e9ecef; padding: 2px 6px; border-radius: 4px; font-family: 'Consolas', monospace; }
76
+ .status { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 8px; }
77
+ .online { background: #28a745; }
78
+ .card { background: white; padding: 20px; border-radius: 8px; margin: 20px 0; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
79
+ </style>
80
+ </head>
81
+ <body>
82
+ <h1>🦬 YAKMESH Self-Contained Node</h1>
83
+ <p>Your complete Yakmesh stack is running.</p>
84
+
85
+ <div class="card">
86
+ <h2>Services</h2>
87
+ <p><span class="status online"></span><strong>Web Server:</strong> <a href="http://localhost:8080">http://localhost:8080</a></p>
88
+ <p><span class="status online"></span><strong>Content API:</strong> <a href="http://localhost:3000/content">http://localhost:3000/content</a></p>
89
+ <p><span class="status online"></span><strong>PHP:</strong> <a href="http://localhost:8080/info.php">http://localhost:8080/info.php</a></p>
90
+ <p><span class="status online"></span><strong>Mesh P2P:</strong> <code>ws://localhost:9001</code></p>
91
+ </div>
92
+
93
+ <div class="card">
94
+ <h2>Content API</h2>
95
+ <ul>
96
+ <li><code>GET /content</code> - List all content</li>
97
+ <li><code>GET /content/:hash</code> - Get content by hash</li>
98
+ <li><code>POST /content</code> - Store new content</li>
99
+ </ul>
100
+ </div>
101
+
102
+ <div class="card">
103
+ <h2>Bundled Software</h2>
104
+ <ul>
105
+ <li>Node.js 20 LTS</li>
106
+ <li>PHP 8.3</li>
107
+ <li>Caddy 2.8</li>
108
+ <li>7-Zip CLI</li>
109
+ </ul>
110
+ </div>
111
+
112
+ <p><a href="https://yakmesh.dev">yakmesh.dev</a> | <a href="https://github.com/yakmesh/yakmesh">GitHub</a></p>
113
+ </body>
114
+ </html>
115
+ "@ | Out-File -FilePath $indexPath -Encoding utf8
116
+ }
117
+
118
+ # Create PHP info file
119
+ $phpInfoPath = Join-Path $ScriptDir "htdocs\info.php"
120
+ if (-not (Test-Path $phpInfoPath)) {
121
+ @"
122
+ <?php
123
+ phpinfo();
124
+ "@ | Out-File -FilePath $phpInfoPath -Encoding utf8
125
+ }
126
+
127
+ # Install node_modules using bundled Node if needed
128
+ if (-not (Test-Path "node_modules")) {
129
+ Write-Host "[INFO] Installing Node.js dependencies..." -ForegroundColor Yellow
130
+ $env:PATH = "$(Split-Path $nodeBin);$env:PATH"
131
+ & $nodeBin (Get-Command npm).Source install 2>&1 | Out-Null
132
+ }
133
+
134
+ Write-Host ""
135
+ Write-Host "[INFO] Starting services..." -ForegroundColor Yellow
136
+ Write-Host ""
137
+
138
+ # Start PHP FastCGI
139
+ $phpJob = Start-Process -FilePath $phpBin -ArgumentList "-b", "127.0.0.1:9000", "-c", $phpIni -WindowStyle Hidden -PassThru
140
+ Write-Host " ✓ PHP FastCGI started (PID: $($phpJob.Id))" -ForegroundColor Green
141
+
142
+ # Start Yakmesh node using bundled Node
143
+ $env:YAKMESH_CONFIG = Join-Path $ScriptDir "config\yakmesh.config.js"
144
+ $meshJob = Start-Process -FilePath $nodeBin -ArgumentList "server/index.js" -WorkingDirectory $ScriptDir -WindowStyle Hidden -PassThru
145
+ Write-Host " ✓ Mesh Node started (PID: $($meshJob.Id))" -ForegroundColor Green
146
+
147
+ Start-Sleep -Seconds 2
148
+
149
+ # Start Caddy
150
+ $caddyfile = Join-Path $ScriptDir "config\Caddyfile"
151
+ $caddyJob = Start-Process -FilePath $caddyBin -ArgumentList "run", "--config", $caddyfile -WorkingDirectory $ScriptDir -WindowStyle Hidden -PassThru
152
+ Write-Host " ✓ Caddy started (PID: $($caddyJob.Id))" -ForegroundColor Green
153
+
154
+ Write-Host ""
155
+ Write-Host " ========================================" -ForegroundColor Green
156
+ Write-Host " All services running!" -ForegroundColor Green
157
+ Write-Host " ========================================" -ForegroundColor Green
158
+ Write-Host ""
159
+ Write-Host " Web Server: http://localhost:8080" -ForegroundColor Cyan
160
+ Write-Host " PHP Info: http://localhost:8080/info.php" -ForegroundColor Cyan
161
+ Write-Host " Content API: http://localhost:3000/content" -ForegroundColor Cyan
162
+ Write-Host " Mesh P2P: ws://localhost:9001" -ForegroundColor Cyan
163
+ Write-Host ""
164
+ Write-Host " Press any key to stop all services..." -ForegroundColor Yellow
165
+ Write-Host ""
166
+
167
+ # Save PIDs
168
+ @{
169
+ php = $phpJob.Id
170
+ mesh = $meshJob.Id
171
+ caddy = $caddyJob.Id
172
+ startTime = Get-Date -Format "o"
173
+ } | ConvertTo-Json | Out-File (Join-Path $ScriptDir "data\.pids.json")
174
+
175
+ # Wait for keypress
176
+ $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
177
+
178
+ Write-Host ""
179
+ Write-Host "[INFO] Shutting down..." -ForegroundColor Yellow
180
+
181
+ # Stop all processes
182
+ Stop-Process -Id $caddyJob.Id -Force -ErrorAction SilentlyContinue
183
+ Stop-Process -Id $meshJob.Id -Force -ErrorAction SilentlyContinue
184
+ Stop-Process -Id $phpJob.Id -Force -ErrorAction SilentlyContinue
185
+
186
+ # Clean up any orphans
187
+ Get-Process -Name "caddy", "php-cgi", "node" -ErrorAction SilentlyContinue |
188
+ Where-Object { $_.Path -like "*yakmesh*" } |
189
+ Stop-Process -Force -ErrorAction SilentlyContinue
190
+
191
+ Remove-Item (Join-Path $ScriptDir "data\.pids.json") -ErrorAction SilentlyContinue
192
+
193
+ Write-Host "[OK] All services stopped" -ForegroundColor Green
@@ -0,0 +1,35 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Stop YAKMESH Self-Contained Node
4
+ #>
5
+
6
+ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
7
+ $pidsFile = Join-Path $ScriptDir "data\.pids.json"
8
+
9
+ Write-Host ""
10
+ Write-Host "[INFO] Stopping YAKMESH services..." -ForegroundColor Yellow
11
+
12
+ # Load PIDs if available
13
+ if (Test-Path $pidsFile) {
14
+ $pids = Get-Content $pidsFile | ConvertFrom-Json
15
+
16
+ if ($pids.caddy) { Stop-Process -Id $pids.caddy -Force -ErrorAction SilentlyContinue }
17
+ if ($pids.mesh) { Stop-Process -Id $pids.mesh -Force -ErrorAction SilentlyContinue }
18
+ if ($pids.php) { Stop-Process -Id $pids.php -Force -ErrorAction SilentlyContinue }
19
+
20
+ Remove-Item $pidsFile -ErrorAction SilentlyContinue
21
+ }
22
+
23
+ # Also stop by name in case PIDs are stale
24
+ Get-Process -Name "caddy" -ErrorAction SilentlyContinue | Stop-Process -Force
25
+ Get-Process -Name "php-cgi" -ErrorAction SilentlyContinue | Stop-Process -Force
26
+ Get-Process -Name "node" -ErrorAction SilentlyContinue | Where-Object {
27
+ $_.Path -like "*yakmesh*"
28
+ } | Stop-Process -Force
29
+
30
+ Write-Host "[OK] Caddy stopped" -ForegroundColor Green
31
+ Write-Host "[OK] PHP stopped" -ForegroundColor Green
32
+ Write-Host "[OK] Mesh node stopped" -ForegroundColor Green
33
+ Write-Host ""
34
+ Write-Host "[OK] All services stopped" -ForegroundColor Green
35
+ Write-Host ""
@@ -0,0 +1,69 @@
1
+ # YAKMESH Minimal Deployment Package
2
+ # Lightweight - downloads dependencies on first run
3
+
4
+ ## Quick Start
5
+
6
+ ```powershell
7
+ .\start.ps1
8
+ ```
9
+
10
+ ## What's Included
11
+
12
+ - ✅ Yakmesh mesh network core
13
+ - ✅ Content delivery API (public HTTP)
14
+ - ✅ Caddy web server (auto-downloads)
15
+ - ✅ Startup/shutdown scripts
16
+
17
+ ## What You Need
18
+
19
+ - Node.js 18+ (must be in PATH)
20
+ - Internet connection (for first-time Caddy download)
21
+ - (Optional) PHP 8+ if you want PHP support
22
+
23
+ ## Configuration
24
+
25
+ Edit `config/yakmesh.config.js` to customize:
26
+
27
+ ```javascript
28
+ export default {
29
+ name: 'My Node',
30
+ port: 9001,
31
+ httpPort: 3000,
32
+ webPort: 8080,
33
+ bootstrap: [], // Add peer addresses here
34
+ };
35
+ ```
36
+
37
+ ## Adding PHP Support
38
+
39
+ 1. Install PHP and ensure `php-cgi` is in PATH
40
+ 2. Edit config:
41
+ ```javascript
42
+ php: {
43
+ enabled: true,
44
+ port: 9000,
45
+ }
46
+ ```
47
+ 3. Restart the node
48
+
49
+ ## Services
50
+
51
+ | URL | Service |
52
+ |-----|---------|
53
+ | http://localhost:9001 | Mesh P2P (WebSocket) |
54
+ | http://localhost:3000 | Content API |
55
+ | http://localhost:8080 | Web Server (Caddy) |
56
+
57
+ ## Directory Structure
58
+
59
+ ```
60
+ yakmesh-minimal/
61
+ ├── bin/ # Caddy downloads here
62
+ ├── config/ # Configuration files
63
+ ├── htdocs/ # Your website files
64
+ ├── data/ # Persistent data
65
+ ├── logs/ # Log files
66
+ ├── start.ps1 # Start everything
67
+ ├── stop.ps1 # Stop everything
68
+ └── README.md # This file
69
+ ```
@@ -0,0 +1,46 @@
1
+ # YAKMESH Minimal - Caddyfile
2
+ # Auto-generated - edit as needed
3
+
4
+ {
5
+ # Disable admin API for security
6
+ admin off
7
+
8
+ # Disable automatic HTTPS (enable for production)
9
+ auto_https off
10
+ }
11
+
12
+ # Main site - HTTP only
13
+ :8080 {
14
+ root * ./htdocs
15
+
16
+ # Enable file server
17
+ file_server
18
+
19
+ # PHP handling (uncomment if PHP enabled)
20
+ # @phpFiles path *.php
21
+ # handle @phpFiles {
22
+ # reverse_proxy localhost:9000
23
+ # }
24
+
25
+ # Security headers
26
+ header {
27
+ X-Content-Type-Options nosniff
28
+ X-Frame-Options DENY
29
+ X-XSS-Protection "1; mode=block"
30
+ Referrer-Policy strict-origin-when-cross-origin
31
+ -Server
32
+ }
33
+
34
+ # Logging
35
+ log {
36
+ output file ./logs/caddy-access.log
37
+ format json
38
+ }
39
+ }
40
+
41
+ # Reverse proxy to Content API
42
+ :8080 {
43
+ handle /content/* {
44
+ reverse_proxy localhost:3000
45
+ }
46
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * YAKMESH Minimal Configuration
3
+ * Edit this file to customize your node
4
+ */
5
+
6
+ export default {
7
+ // ========================================
8
+ // NODE IDENTITY
9
+ // ========================================
10
+ name: 'Yakmesh Node',
11
+
12
+ // ========================================
13
+ // NETWORK PORTS
14
+ // ========================================
15
+ port: 9001, // Mesh P2P WebSocket
16
+ httpPort: 3000, // Content API (public HTTP)
17
+ webPort: 8080, // Caddy web server
18
+
19
+ // ========================================
20
+ // BOOTSTRAP PEERS
21
+ // ========================================
22
+ // Add peer addresses to join an existing network
23
+ // Leave empty to start a standalone node
24
+ bootstrap: [
25
+ // 'ws://peer1.example.com:9001',
26
+ // 'ws://192.168.1.100:9001',
27
+ ],
28
+
29
+ // ========================================
30
+ // WEB SERVER (CADDY)
31
+ // ========================================
32
+ web: {
33
+ enabled: true,
34
+ port: 8080,
35
+ root: './htdocs',
36
+ autoHttps: false, // Enable for production with domain
37
+ domain: null, // e.g., 'mysite.example.com'
38
+ },
39
+
40
+ // ========================================
41
+ // PHP SUPPORT (Optional)
42
+ // ========================================
43
+ // Requires php-cgi in PATH (minimal package)
44
+ php: {
45
+ enabled: false,
46
+ port: 9000,
47
+ // binary: 'php-cgi', // Custom path if needed
48
+ },
49
+
50
+ // ========================================
51
+ // CONTENT DELIVERY
52
+ // ========================================
53
+ content: {
54
+ enabled: true,
55
+ storagePath: './data/content',
56
+ maxSize: 100 * 1024 * 1024, // 100 MB per item
57
+ cacheMaxAge: 86400, // 24 hours
58
+ },
59
+
60
+ // ========================================
61
+ // SECURITY
62
+ // ========================================
63
+ security: {
64
+ enableCodeProof: true, // Verify peer code integrity
65
+ rateLimit: {
66
+ windowMs: 60000, // 1 minute
67
+ maxRequests: 100, // Per IP
68
+ },
69
+ },
70
+
71
+ // ========================================
72
+ // LOGGING
73
+ // ========================================
74
+ logging: {
75
+ level: 'info', // debug, info, warn, error
76
+ path: './logs',
77
+ maxFiles: 7, // Days to keep
78
+ },
79
+ };
@@ -0,0 +1,165 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Start YAKMESH Minimal Node
4
+
5
+ .DESCRIPTION
6
+ Starts the Yakmesh mesh node, content API, and Caddy web server.
7
+ Downloads Caddy on first run if not present.
8
+ #>
9
+
10
+ $ErrorActionPreference = "Stop"
11
+ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
12
+ Set-Location $ScriptDir
13
+
14
+ Write-Host ""
15
+ Write-Host " =====================================" -ForegroundColor Cyan
16
+ Write-Host " YAKMESH MINIMAL NODE" -ForegroundColor Cyan
17
+ Write-Host " Mesh Network + Web Server" -ForegroundColor Cyan
18
+ Write-Host " =====================================" -ForegroundColor Cyan
19
+ Write-Host ""
20
+
21
+ # Check Node.js
22
+ $nodeVersion = & node --version 2>$null
23
+ if (-not $nodeVersion) {
24
+ Write-Host "[ERROR] Node.js not found. Please install Node.js 18+ and add to PATH." -ForegroundColor Red
25
+ exit 1
26
+ }
27
+ Write-Host "[OK] Node.js $nodeVersion" -ForegroundColor Green
28
+
29
+ # Check/Install dependencies
30
+ if (-not (Test-Path "node_modules")) {
31
+ Write-Host "[INFO] Installing dependencies..." -ForegroundColor Yellow
32
+ & npm install
33
+ }
34
+
35
+ # Check Caddy
36
+ $caddyPath = Join-Path $ScriptDir "bin\caddy.exe"
37
+ if (-not (Test-Path $caddyPath)) {
38
+ Write-Host "[INFO] Downloading Caddy web server..." -ForegroundColor Yellow
39
+
40
+ # Create bin directory
41
+ New-Item -ItemType Directory -Path (Join-Path $ScriptDir "bin") -Force | Out-Null
42
+
43
+ # Download Caddy
44
+ $caddyUrl = "https://github.com/caddyserver/caddy/releases/download/v2.8.4/caddy_2.8.4_windows_amd64.zip"
45
+ $zipPath = Join-Path $ScriptDir "bin\caddy.zip"
46
+
47
+ Invoke-WebRequest -Uri $caddyUrl -OutFile $zipPath
48
+ Expand-Archive -Path $zipPath -DestinationPath (Join-Path $ScriptDir "bin") -Force
49
+ Remove-Item $zipPath
50
+
51
+ Write-Host "[OK] Caddy installed" -ForegroundColor Green
52
+ }
53
+
54
+ # Create directories
55
+ @("htdocs", "data", "data\content", "logs") | ForEach-Object {
56
+ $dir = Join-Path $ScriptDir $_
57
+ if (-not (Test-Path $dir)) {
58
+ New-Item -ItemType Directory -Path $dir -Force | Out-Null
59
+ }
60
+ }
61
+
62
+ # Create default index.html if not exists
63
+ $indexPath = Join-Path $ScriptDir "htdocs\index.html"
64
+ if (-not (Test-Path $indexPath)) {
65
+ @"
66
+ <!DOCTYPE html>
67
+ <html>
68
+ <head>
69
+ <title>YAKMESH Node</title>
70
+ <style>
71
+ body { font-family: system-ui; max-width: 800px; margin: 50px auto; padding: 20px; }
72
+ h1 { color: #2d5016; }
73
+ code { background: #f4f4f4; padding: 2px 6px; border-radius: 4px; }
74
+ </style>
75
+ </head>
76
+ <body>
77
+ <h1>🦬 YAKMESH Node Running</h1>
78
+ <p>Your Yakmesh node is operational.</p>
79
+ <h2>Endpoints</h2>
80
+ <ul>
81
+ <li><strong>Web Server:</strong> <a href="http://localhost:8080">http://localhost:8080</a></li>
82
+ <li><strong>Content API:</strong> <a href="http://localhost:3000/content">http://localhost:3000/content</a></li>
83
+ <li><strong>Mesh P2P:</strong> <code>ws://localhost:9001</code></li>
84
+ </ul>
85
+ <h2>Content API</h2>
86
+ <ul>
87
+ <li><code>GET /content</code> - List all content</li>
88
+ <li><code>GET /content/:hash</code> - Get content by hash</li>
89
+ <li><code>POST /content</code> - Store new content</li>
90
+ </ul>
91
+ <p><a href="https://yakmesh.dev">yakmesh.dev</a> | <a href="https://github.com/yakmesh/yakmesh">GitHub</a></p>
92
+ </body>
93
+ </html>
94
+ "@ | Out-File -FilePath $indexPath -Encoding utf8
95
+ }
96
+
97
+ Write-Host ""
98
+ Write-Host "[INFO] Starting services..." -ForegroundColor Yellow
99
+ Write-Host ""
100
+
101
+ # Start Yakmesh node in background
102
+ $env:YAKMESH_CONFIG = Join-Path $ScriptDir "config\yakmesh.config.js"
103
+ $meshJob = Start-Job -ScriptBlock {
104
+ param($dir)
105
+ Set-Location $dir
106
+ & node server/index.js 2>&1
107
+ } -ArgumentList $ScriptDir
108
+
109
+ # Give mesh node time to start
110
+ Start-Sleep -Seconds 2
111
+
112
+ # Start Caddy
113
+ $caddyfile = Join-Path $ScriptDir "config\Caddyfile"
114
+ $caddyJob = Start-Job -ScriptBlock {
115
+ param($caddy, $config, $dir)
116
+ Set-Location $dir
117
+ & $caddy run --config $config 2>&1
118
+ } -ArgumentList $caddyPath, $caddyfile, $ScriptDir
119
+
120
+ Write-Host ""
121
+ Write-Host " ✓ Mesh Node: ws://localhost:9001" -ForegroundColor Green
122
+ Write-Host " ✓ Content API: http://localhost:3000" -ForegroundColor Green
123
+ Write-Host " ✓ Web Server: http://localhost:8080" -ForegroundColor Green
124
+ Write-Host ""
125
+ Write-Host " Press Ctrl+C to stop all services" -ForegroundColor Yellow
126
+ Write-Host ""
127
+
128
+ # Save PIDs for stop script
129
+ @{
130
+ meshJobId = $meshJob.Id
131
+ caddyJobId = $caddyJob.Id
132
+ startTime = Get-Date -Format "o"
133
+ } | ConvertTo-Json | Out-File (Join-Path $ScriptDir "data\.pids.json")
134
+
135
+ # Wait and handle Ctrl+C
136
+ try {
137
+ while ($true) {
138
+ Start-Sleep -Seconds 1
139
+
140
+ # Check if jobs are still running
141
+ $meshState = Get-Job -Id $meshJob.Id -ErrorAction SilentlyContinue
142
+ $caddyState = Get-Job -Id $caddyJob.Id -ErrorAction SilentlyContinue
143
+
144
+ if ($meshState.State -eq "Failed" -or $caddyState.State -eq "Failed") {
145
+ Write-Host "[ERROR] A service has stopped unexpectedly" -ForegroundColor Red
146
+ break
147
+ }
148
+ }
149
+ }
150
+ finally {
151
+ Write-Host ""
152
+ Write-Host "[INFO] Shutting down..." -ForegroundColor Yellow
153
+
154
+ Stop-Job -Id $meshJob.Id -ErrorAction SilentlyContinue
155
+ Stop-Job -Id $caddyJob.Id -ErrorAction SilentlyContinue
156
+ Remove-Job -Id $meshJob.Id -Force -ErrorAction SilentlyContinue
157
+ Remove-Job -Id $caddyJob.Id -Force -ErrorAction SilentlyContinue
158
+
159
+ # Also kill any orphan processes
160
+ Get-Process -Name "caddy" -ErrorAction SilentlyContinue | Stop-Process -Force
161
+
162
+ Remove-Item (Join-Path $ScriptDir "data\.pids.json") -ErrorAction SilentlyContinue
163
+
164
+ Write-Host "[OK] All services stopped" -ForegroundColor Green
165
+ }
@@ -0,0 +1,29 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Stop YAKMESH Minimal Node
4
+ #>
5
+
6
+ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
7
+ $pidsFile = Join-Path $ScriptDir "data\.pids.json"
8
+
9
+ Write-Host ""
10
+ Write-Host "[INFO] Stopping YAKMESH services..." -ForegroundColor Yellow
11
+
12
+ # Stop Caddy
13
+ Get-Process -Name "caddy" -ErrorAction SilentlyContinue | Stop-Process -Force
14
+ Write-Host "[OK] Caddy stopped" -ForegroundColor Green
15
+
16
+ # Stop Node processes for this directory
17
+ Get-Process -Name "node" -ErrorAction SilentlyContinue | Where-Object {
18
+ $_.Path -like "*yakmesh*"
19
+ } | Stop-Process -Force
20
+ Write-Host "[OK] Node processes stopped" -ForegroundColor Green
21
+
22
+ # Clean up PID file
23
+ if (Test-Path $pidsFile) {
24
+ Remove-Item $pidsFile
25
+ }
26
+
27
+ Write-Host ""
28
+ Write-Host "[OK] All services stopped" -ForegroundColor Green
29
+ Write-Host ""