fss-link 1.5.7 → 1.6.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.
- package/README.md +1 -1
- package/bundle/fss-link.js +4785 -3183
- package/package.json +4 -1
- package/scripts/analyze-session-logs.sh +279 -0
- package/scripts/build.js +55 -0
- package/scripts/build_package.js +37 -0
- package/scripts/build_sandbox.js +195 -0
- package/scripts/build_vscode_companion.js +30 -0
- package/scripts/check-build-status.js +148 -0
- package/scripts/check-publish.js +101 -0
- package/scripts/clean.js +55 -0
- package/scripts/copy_bundle_assets.js +40 -0
- package/scripts/copy_files.js +56 -0
- package/scripts/create_alias.sh +39 -0
- package/scripts/emergency-kill-all-tests.sh +95 -0
- package/scripts/emergency-kill-vitest.sh +95 -0
- package/scripts/extract-session-logs.sh +202 -0
- package/scripts/generate-git-commit-info.js +71 -0
- package/scripts/get-previous-tag.js +213 -0
- package/scripts/get-release-version.js +119 -0
- package/scripts/index-session-logs.sh +173 -0
- package/scripts/install-linux.sh +294 -0
- package/scripts/install-macos.sh +343 -0
- package/scripts/install-windows.ps1 +427 -0
- package/scripts/local_telemetry.js +219 -0
- package/scripts/memory-monitor.sh +165 -0
- package/scripts/postinstall-message.js +31 -0
- package/scripts/prepare-package.js +51 -0
- package/scripts/process-session-log.py +302 -0
- package/scripts/quick-install.sh +195 -0
- package/scripts/sandbox_command.js +126 -0
- package/scripts/start.js +76 -0
- package/scripts/telemetry.js +85 -0
- package/scripts/telemetry_gcp.js +188 -0
- package/scripts/telemetry_utils.js +421 -0
- package/scripts/test-windows-paths.js +51 -0
- package/scripts/tests/get-release-version.test.js +110 -0
- package/scripts/tests/test-setup.ts +12 -0
- package/scripts/tests/vitest.config.ts +20 -0
- package/scripts/version.js +83 -0
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
# FSS Link Windows Installation Script
|
|
2
|
+
# Supports Windows 10+ with automatic dependency management
|
|
3
|
+
|
|
4
|
+
param(
|
|
5
|
+
[switch]$Help,
|
|
6
|
+
[switch]$Version,
|
|
7
|
+
[switch]$Force,
|
|
8
|
+
[switch]$NoChocolatey
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
# Color output functions
|
|
12
|
+
function Write-Info {
|
|
13
|
+
param([string]$Message)
|
|
14
|
+
Write-Host "[INFO] $Message" -ForegroundColor Blue
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function Write-Success {
|
|
18
|
+
param([string]$Message)
|
|
19
|
+
Write-Host "[SUCCESS] $Message" -ForegroundColor Green
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function Write-Warning {
|
|
23
|
+
param([string]$Message)
|
|
24
|
+
Write-Host "[WARNING] $Message" -ForegroundColor Yellow
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function Write-Error {
|
|
28
|
+
param([string]$Message)
|
|
29
|
+
Write-Host "[ERROR] $Message" -ForegroundColor Red
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Check if running as Administrator
|
|
33
|
+
function Test-Administrator {
|
|
34
|
+
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
|
|
35
|
+
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
|
|
36
|
+
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# Check Windows version
|
|
40
|
+
function Test-WindowsVersion {
|
|
41
|
+
Write-Info "Checking Windows version..."
|
|
42
|
+
|
|
43
|
+
$version = [System.Environment]::OSVersion.Version
|
|
44
|
+
$buildNumber = (Get-ItemProperty "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseId
|
|
45
|
+
|
|
46
|
+
Write-Info "Windows version: $($version.Major).$($version.Minor) Build $buildNumber"
|
|
47
|
+
|
|
48
|
+
if ($version.Major -ge 10) {
|
|
49
|
+
Write-Success "Windows version supported"
|
|
50
|
+
return $true
|
|
51
|
+
} else {
|
|
52
|
+
Write-Error "Windows 10+ required, found Windows $($version.Major).$($version.Minor)"
|
|
53
|
+
return $false
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
# Check for Node.js
|
|
58
|
+
function Test-NodeJS {
|
|
59
|
+
Write-Info "Checking Node.js installation..."
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
$nodeVersion = & node --version 2>$null
|
|
63
|
+
if ($nodeVersion) {
|
|
64
|
+
$version = $nodeVersion.TrimStart('v')
|
|
65
|
+
$majorVersion = [int]($version.Split('.')[0])
|
|
66
|
+
|
|
67
|
+
if ($majorVersion -ge 20) {
|
|
68
|
+
Write-Success "Node.js $nodeVersion detected (>= 20.0.0 required)"
|
|
69
|
+
return $true
|
|
70
|
+
} else {
|
|
71
|
+
Write-Warning "Node.js $nodeVersion detected, but 20.0.0+ required"
|
|
72
|
+
return $false
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
76
|
+
Write-Warning "Node.js not found"
|
|
77
|
+
return $false
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return $false
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
# Check for Chocolatey
|
|
84
|
+
function Test-Chocolatey {
|
|
85
|
+
Write-Info "Checking for Chocolatey package manager..."
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
$chocoVersion = & choco --version 2>$null
|
|
89
|
+
if ($chocoVersion) {
|
|
90
|
+
Write-Success "Chocolatey $chocoVersion found"
|
|
91
|
+
return $true
|
|
92
|
+
}
|
|
93
|
+
} catch {
|
|
94
|
+
Write-Warning "Chocolatey not found"
|
|
95
|
+
return $false
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return $false
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# Install Chocolatey
|
|
102
|
+
function Install-Chocolatey {
|
|
103
|
+
Write-Info "Installing Chocolatey package manager..."
|
|
104
|
+
|
|
105
|
+
Set-ExecutionPolicy Bypass -Scope Process -Force
|
|
106
|
+
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
|
|
110
|
+
|
|
111
|
+
# Refresh environment variables
|
|
112
|
+
$env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("PATH", "User")
|
|
113
|
+
|
|
114
|
+
if (Test-Chocolatey) {
|
|
115
|
+
Write-Success "Chocolatey installed successfully"
|
|
116
|
+
return $true
|
|
117
|
+
} else {
|
|
118
|
+
Write-Error "Chocolatey installation verification failed"
|
|
119
|
+
return $false
|
|
120
|
+
}
|
|
121
|
+
} catch {
|
|
122
|
+
Write-Error "Chocolatey installation failed: $($_.Exception.Message)"
|
|
123
|
+
return $false
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# Install Node.js
|
|
128
|
+
function Install-NodeJS {
|
|
129
|
+
Write-Info "Installing Node.js 20..."
|
|
130
|
+
|
|
131
|
+
if ($NoChocolatey) {
|
|
132
|
+
Write-Info "Manual Node.js installation selected"
|
|
133
|
+
Write-Info "Please download and install Node.js 20+ from https://nodejs.org/"
|
|
134
|
+
Write-Info "Press Enter when installation is complete..."
|
|
135
|
+
Read-Host
|
|
136
|
+
|
|
137
|
+
if (Test-NodeJS) {
|
|
138
|
+
Write-Success "Node.js installed successfully"
|
|
139
|
+
return $true
|
|
140
|
+
} else {
|
|
141
|
+
Write-Error "Node.js installation verification failed"
|
|
142
|
+
return $false
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
try {
|
|
146
|
+
# Install Node.js via Chocolatey
|
|
147
|
+
& choco install nodejs --version=20.11.0 -y
|
|
148
|
+
|
|
149
|
+
# Refresh environment variables
|
|
150
|
+
$env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("PATH", "User")
|
|
151
|
+
|
|
152
|
+
if (Test-NodeJS) {
|
|
153
|
+
Write-Success "Node.js installed successfully"
|
|
154
|
+
return $true
|
|
155
|
+
} else {
|
|
156
|
+
Write-Error "Node.js installation verification failed"
|
|
157
|
+
return $false
|
|
158
|
+
}
|
|
159
|
+
} catch {
|
|
160
|
+
Write-Error "Node.js installation failed: $($_.Exception.Message)"
|
|
161
|
+
return $false
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
# Install Visual Studio Build Tools
|
|
167
|
+
function Install-BuildTools {
|
|
168
|
+
Write-Info "Installing Visual Studio Build Tools..."
|
|
169
|
+
|
|
170
|
+
if ($NoChocolatey) {
|
|
171
|
+
Write-Info "Please install Visual Studio Build Tools 2019 or later manually"
|
|
172
|
+
Write-Info "Download from: https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019"
|
|
173
|
+
Write-Info "Press Enter when installation is complete..."
|
|
174
|
+
Read-Host
|
|
175
|
+
return $true
|
|
176
|
+
} else {
|
|
177
|
+
try {
|
|
178
|
+
& choco install visualstudio2019buildtools -y
|
|
179
|
+
Write-Success "Visual Studio Build Tools installed"
|
|
180
|
+
return $true
|
|
181
|
+
} catch {
|
|
182
|
+
Write-Warning "Build tools installation may have failed: $($_.Exception.Message)"
|
|
183
|
+
Write-Info "FSS Link installation will continue, but native modules may not compile"
|
|
184
|
+
return $true
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
# Install Python
|
|
190
|
+
function Install-Python {
|
|
191
|
+
Write-Info "Installing Python 3..."
|
|
192
|
+
|
|
193
|
+
if ($NoChocolatey) {
|
|
194
|
+
Write-Info "Please install Python 3.8+ manually from https://python.org/"
|
|
195
|
+
Write-Info "Press Enter when installation is complete..."
|
|
196
|
+
Read-Host
|
|
197
|
+
return $true
|
|
198
|
+
} else {
|
|
199
|
+
try {
|
|
200
|
+
& choco install python3 -y
|
|
201
|
+
|
|
202
|
+
# Refresh PATH
|
|
203
|
+
$env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("PATH", "User")
|
|
204
|
+
|
|
205
|
+
Write-Success "Python 3 installed"
|
|
206
|
+
return $true
|
|
207
|
+
} catch {
|
|
208
|
+
Write-Warning "Python installation may have failed: $($_.Exception.Message)"
|
|
209
|
+
return $true
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
# Install FSS Link
|
|
215
|
+
function Install-FSSLink {
|
|
216
|
+
Write-Info "Installing FSS Link..."
|
|
217
|
+
|
|
218
|
+
try {
|
|
219
|
+
# Try global installation first
|
|
220
|
+
& npm install -g fss-link
|
|
221
|
+
|
|
222
|
+
if (Test-FSSLink) {
|
|
223
|
+
Write-Success "FSS Link installed globally"
|
|
224
|
+
return $true
|
|
225
|
+
} else {
|
|
226
|
+
throw "Global installation verification failed"
|
|
227
|
+
}
|
|
228
|
+
} catch {
|
|
229
|
+
Write-Warning "Global installation failed, trying alternative approach: $($_.Exception.Message)"
|
|
230
|
+
|
|
231
|
+
try {
|
|
232
|
+
# Create local npm directory
|
|
233
|
+
$npmGlobalPath = "$env:USERPROFILE\.npm-global"
|
|
234
|
+
New-Item -ItemType Directory -Path $npmGlobalPath -Force | Out-Null
|
|
235
|
+
|
|
236
|
+
& npm config set prefix $npmGlobalPath
|
|
237
|
+
|
|
238
|
+
# Add to PATH
|
|
239
|
+
$userPath = [System.Environment]::GetEnvironmentVariable("PATH", "User")
|
|
240
|
+
$npmBinPath = "$npmGlobalPath\bin"
|
|
241
|
+
|
|
242
|
+
if ($userPath -notlike "*$npmBinPath*") {
|
|
243
|
+
[System.Environment]::SetEnvironmentVariable("PATH", "$userPath;$npmBinPath", "User")
|
|
244
|
+
$env:PATH = "$env:PATH;$npmBinPath"
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
# Install locally
|
|
248
|
+
& npm install -g fss-link
|
|
249
|
+
|
|
250
|
+
Write-Success "FSS Link installed locally"
|
|
251
|
+
return $true
|
|
252
|
+
} catch {
|
|
253
|
+
Write-Error "FSS Link installation failed: $($_.Exception.Message)"
|
|
254
|
+
return $false
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
# Test FSS Link installation
|
|
260
|
+
function Test-FSSLink {
|
|
261
|
+
try {
|
|
262
|
+
$fssVersion = & fss-link --version 2>$null
|
|
263
|
+
if ($fssVersion) {
|
|
264
|
+
Write-Success "FSS Link installed successfully: $fssVersion"
|
|
265
|
+
return $true
|
|
266
|
+
}
|
|
267
|
+
} catch {
|
|
268
|
+
return $false
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return $false
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
# Verify FSS Link functionality
|
|
275
|
+
function Test-FSSLinkFunctionality {
|
|
276
|
+
Write-Info "Running FSS Link functionality tests..."
|
|
277
|
+
|
|
278
|
+
try {
|
|
279
|
+
# Test help command
|
|
280
|
+
$helpOutput = & fss-link --help 2>$null
|
|
281
|
+
if ($helpOutput) {
|
|
282
|
+
Write-Success "✅ Help command working"
|
|
283
|
+
} else {
|
|
284
|
+
Write-Warning "⚠️ Help command failed"
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
# Test parsers
|
|
288
|
+
$parsersOutput = & fss-link test-parsers 2>$null
|
|
289
|
+
if ($parsersOutput) {
|
|
290
|
+
Write-Success "✅ Document parsers working"
|
|
291
|
+
} else {
|
|
292
|
+
Write-Warning "⚠️ Document parsers test failed"
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return $true
|
|
296
|
+
} catch {
|
|
297
|
+
Write-Warning "Some functionality tests failed: $($_.Exception.Message)"
|
|
298
|
+
return $false
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
# Print usage information
|
|
303
|
+
function Show-Usage {
|
|
304
|
+
Write-Host @"
|
|
305
|
+
|
|
306
|
+
🚀 FSS Link Installation Complete!
|
|
307
|
+
|
|
308
|
+
📋 Quick Start:
|
|
309
|
+
fss-link --version # Check version
|
|
310
|
+
fss-link --help # Show help
|
|
311
|
+
fss-link test-parsers # Test document processing
|
|
312
|
+
|
|
313
|
+
🔧 Configuration:
|
|
314
|
+
fss-link init # Initialize configuration
|
|
315
|
+
fss-link models setup # Set up model profiles
|
|
316
|
+
|
|
317
|
+
📚 Documentation:
|
|
318
|
+
https://github.com/FSSCoding/fss-link/blob/main/INSTALLATION.md
|
|
319
|
+
https://github.com/FSSCoding/fss-link/blob/main/fss-docs/README.md
|
|
320
|
+
|
|
321
|
+
🎯 Example Usage:
|
|
322
|
+
fss-link -p "analyze this project"
|
|
323
|
+
fss-link --tools excel-parser -p "parse spreadsheet.xlsx"
|
|
324
|
+
fss-link --tools web-scraper -p "scrape https://example.com"
|
|
325
|
+
|
|
326
|
+
💻 Windows Specific:
|
|
327
|
+
- FSS Link is now in your PATH
|
|
328
|
+
- Restart PowerShell/Command Prompt to ensure PATH changes take effect
|
|
329
|
+
- Use Windows Terminal for the best experience
|
|
330
|
+
|
|
331
|
+
"@ -ForegroundColor Cyan
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
# Main installation flow
|
|
335
|
+
function Main {
|
|
336
|
+
Write-Host "🚀 FSS Link Windows Installation Script" -ForegroundColor Cyan
|
|
337
|
+
Write-Host "=======================================" -ForegroundColor Cyan
|
|
338
|
+
Write-Host ""
|
|
339
|
+
|
|
340
|
+
# Check if running as administrator
|
|
341
|
+
if (Test-Administrator) {
|
|
342
|
+
Write-Warning "Running as Administrator. FSS Link will be installed globally."
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
# Check Windows version
|
|
346
|
+
if (-not (Test-WindowsVersion)) {
|
|
347
|
+
exit 1
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
# Install Chocolatey if needed (unless disabled)
|
|
351
|
+
if (-not $NoChocolatey -and -not (Test-Chocolatey)) {
|
|
352
|
+
Write-Info "Installing Chocolatey for automated dependency management..."
|
|
353
|
+
if (-not (Install-Chocolatey)) {
|
|
354
|
+
Write-Error "Chocolatey installation failed"
|
|
355
|
+
Write-Info "Re-run with -NoChocolatey flag for manual installation"
|
|
356
|
+
exit 1
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
# Install Node.js if needed
|
|
361
|
+
if (-not (Test-NodeJS)) {
|
|
362
|
+
if (-not (Install-NodeJS)) {
|
|
363
|
+
Write-Error "Node.js installation failed"
|
|
364
|
+
exit 1
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
# Install build tools
|
|
369
|
+
Install-BuildTools | Out-Null
|
|
370
|
+
|
|
371
|
+
# Install Python
|
|
372
|
+
Install-Python | Out-Null
|
|
373
|
+
|
|
374
|
+
# Install FSS Link
|
|
375
|
+
if (-not (Install-FSSLink)) {
|
|
376
|
+
Write-Error "FSS Link installation failed"
|
|
377
|
+
Write-Info "Please check the installation manually or report issues at:"
|
|
378
|
+
Write-Info "https://github.com/FSSCoding/fss-link/issues"
|
|
379
|
+
exit 1
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
# Verify installation
|
|
383
|
+
Test-FSSLinkFunctionality | Out-Null
|
|
384
|
+
|
|
385
|
+
Show-Usage
|
|
386
|
+
Write-Success "🎉 FSS Link installation successful!"
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
# Handle script parameters
|
|
390
|
+
if ($Help) {
|
|
391
|
+
Write-Host @"
|
|
392
|
+
FSS Link Windows Installation Script
|
|
393
|
+
|
|
394
|
+
Usage: .\install-windows.ps1 [options]
|
|
395
|
+
|
|
396
|
+
Options:
|
|
397
|
+
-Help Show this help message
|
|
398
|
+
-Version Show script version
|
|
399
|
+
-Force Force reinstallation
|
|
400
|
+
-NoChocolatey Skip Chocolatey installation (manual mode)
|
|
401
|
+
|
|
402
|
+
This script will:
|
|
403
|
+
1. Check Windows version compatibility
|
|
404
|
+
2. Install Chocolatey package manager (unless -NoChocolatey)
|
|
405
|
+
3. Install Node.js 20+ and dependencies
|
|
406
|
+
4. Install Visual Studio Build Tools
|
|
407
|
+
5. Install FSS Link from npm
|
|
408
|
+
6. Verify the installation
|
|
409
|
+
|
|
410
|
+
Examples:
|
|
411
|
+
.\install-windows.ps1 # Standard installation
|
|
412
|
+
.\install-windows.ps1 -NoChocolatey # Manual installation mode
|
|
413
|
+
.\install-windows.ps1 -Force # Force reinstallation
|
|
414
|
+
"@
|
|
415
|
+
exit 0
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if ($Version) {
|
|
419
|
+
Write-Host "FSS Link Windows Installation Script v1.0.0"
|
|
420
|
+
exit 0
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
# Set execution policy for this session
|
|
424
|
+
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force
|
|
425
|
+
|
|
426
|
+
# Run main installation
|
|
427
|
+
Main
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
* Copyright 2025 Google LLC
|
|
6
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
import { spawn, execSync } from 'child_process';
|
|
12
|
+
import { fileURLToPath } from 'url';
|
|
13
|
+
import {
|
|
14
|
+
BIN_DIR,
|
|
15
|
+
OTEL_DIR,
|
|
16
|
+
ensureBinary,
|
|
17
|
+
fileExists,
|
|
18
|
+
manageTelemetrySettings,
|
|
19
|
+
registerCleanup,
|
|
20
|
+
waitForPort,
|
|
21
|
+
} from './telemetry_utils.js';
|
|
22
|
+
|
|
23
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
24
|
+
const __dirname = path.dirname(__filename);
|
|
25
|
+
|
|
26
|
+
const OTEL_CONFIG_FILE = path.join(OTEL_DIR, 'collector-local.yaml');
|
|
27
|
+
const OTEL_LOG_FILE = path.join(OTEL_DIR, 'collector.log');
|
|
28
|
+
const JAEGER_LOG_FILE = path.join(OTEL_DIR, 'jaeger.log');
|
|
29
|
+
const JAEGER_PORT = 16686;
|
|
30
|
+
|
|
31
|
+
// This configuration is for the primary otelcol-contrib instance.
|
|
32
|
+
// It receives from the CLI on 4317, exports traces to Jaeger on 14317,
|
|
33
|
+
// and sends metrics/logs to the debug log.
|
|
34
|
+
const OTEL_CONFIG_CONTENT = `
|
|
35
|
+
receivers:
|
|
36
|
+
otlp:
|
|
37
|
+
protocols:
|
|
38
|
+
grpc:
|
|
39
|
+
endpoint: "localhost:4317"
|
|
40
|
+
processors:
|
|
41
|
+
batch:
|
|
42
|
+
timeout: 1s
|
|
43
|
+
exporters:
|
|
44
|
+
otlp:
|
|
45
|
+
endpoint: "localhost:14317"
|
|
46
|
+
tls:
|
|
47
|
+
insecure: true
|
|
48
|
+
debug:
|
|
49
|
+
verbosity: detailed
|
|
50
|
+
service:
|
|
51
|
+
telemetry:
|
|
52
|
+
logs:
|
|
53
|
+
level: "debug"
|
|
54
|
+
metrics:
|
|
55
|
+
level: "none"
|
|
56
|
+
pipelines:
|
|
57
|
+
traces:
|
|
58
|
+
receivers: [otlp]
|
|
59
|
+
processors: [batch]
|
|
60
|
+
exporters: [otlp]
|
|
61
|
+
metrics:
|
|
62
|
+
receivers: [otlp]
|
|
63
|
+
processors: [batch]
|
|
64
|
+
exporters: [debug]
|
|
65
|
+
logs:
|
|
66
|
+
receivers: [otlp]
|
|
67
|
+
processors: [batch]
|
|
68
|
+
exporters: [debug]
|
|
69
|
+
`;
|
|
70
|
+
|
|
71
|
+
async function main() {
|
|
72
|
+
// 1. Ensure binaries are available, downloading if necessary.
|
|
73
|
+
// Binaries are stored in the project's .fss-link/otel/bin directory
|
|
74
|
+
// to avoid modifying the user's system.
|
|
75
|
+
if (!fileExists(BIN_DIR)) fs.mkdirSync(BIN_DIR, { recursive: true });
|
|
76
|
+
|
|
77
|
+
const otelcolPath = await ensureBinary(
|
|
78
|
+
'otelcol-contrib',
|
|
79
|
+
'open-telemetry/opentelemetry-collector-releases',
|
|
80
|
+
(version, platform, arch, ext) =>
|
|
81
|
+
`otelcol-contrib_${version}_${platform}_${arch}.${ext}`,
|
|
82
|
+
'otelcol-contrib',
|
|
83
|
+
false, // isJaeger = false
|
|
84
|
+
).catch((e) => {
|
|
85
|
+
console.error(`��� Error getting otelcol-contrib: ${e.message}`);
|
|
86
|
+
return null;
|
|
87
|
+
});
|
|
88
|
+
if (!otelcolPath) process.exit(1);
|
|
89
|
+
|
|
90
|
+
const jaegerPath = await ensureBinary(
|
|
91
|
+
'jaeger',
|
|
92
|
+
'jaegertracing/jaeger',
|
|
93
|
+
(version, platform, arch, ext) =>
|
|
94
|
+
`jaeger-${version}-${platform}-${arch}.${ext}`,
|
|
95
|
+
'jaeger',
|
|
96
|
+
true, // isJaeger = true
|
|
97
|
+
).catch((e) => {
|
|
98
|
+
console.error(`🛑 Error getting jaeger: ${e.message}`);
|
|
99
|
+
return null;
|
|
100
|
+
});
|
|
101
|
+
if (!jaegerPath) process.exit(1);
|
|
102
|
+
|
|
103
|
+
// 2. Kill any existing processes to ensure a clean start.
|
|
104
|
+
console.log('🧹 Cleaning up old processes and logs...');
|
|
105
|
+
try {
|
|
106
|
+
execSync('pkill -f "otelcol-contrib"');
|
|
107
|
+
console.log('✅ Stopped existing otelcol-contrib process.');
|
|
108
|
+
} catch (_e) {} // eslint-disable-line no-empty
|
|
109
|
+
try {
|
|
110
|
+
execSync('pkill -f "jaeger"');
|
|
111
|
+
console.log('✅ Stopped existing jaeger process.');
|
|
112
|
+
} catch (_e) {} // eslint-disable-line no-empty
|
|
113
|
+
try {
|
|
114
|
+
if (fileExists(OTEL_LOG_FILE)) fs.unlinkSync(OTEL_LOG_FILE);
|
|
115
|
+
console.log('✅ Deleted old collector log.');
|
|
116
|
+
} catch (e) {
|
|
117
|
+
if (e.code !== 'ENOENT') console.error(e);
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
if (fileExists(JAEGER_LOG_FILE)) fs.unlinkSync(JAEGER_LOG_FILE);
|
|
121
|
+
console.log('✅ Deleted old jaeger log.');
|
|
122
|
+
} catch (e) {
|
|
123
|
+
if (e.code !== 'ENOENT') console.error(e);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
let jaegerProcess, collectorProcess;
|
|
127
|
+
let jaegerLogFd, collectorLogFd;
|
|
128
|
+
|
|
129
|
+
const originalSandboxSetting = manageTelemetrySettings(
|
|
130
|
+
true,
|
|
131
|
+
'http://localhost:4317',
|
|
132
|
+
'local',
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
registerCleanup(
|
|
136
|
+
() => [jaegerProcess, collectorProcess],
|
|
137
|
+
() => [jaegerLogFd, collectorLogFd],
|
|
138
|
+
originalSandboxSetting,
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
if (!fileExists(OTEL_DIR)) fs.mkdirSync(OTEL_DIR, { recursive: true });
|
|
142
|
+
fs.writeFileSync(OTEL_CONFIG_FILE, OTEL_CONFIG_CONTENT);
|
|
143
|
+
console.log('📄 Wrote OTEL collector config.');
|
|
144
|
+
|
|
145
|
+
// Start Jaeger
|
|
146
|
+
console.log(`🚀 Starting Jaeger service... Logs: ${JAEGER_LOG_FILE}`);
|
|
147
|
+
jaegerLogFd = fs.openSync(JAEGER_LOG_FILE, 'a');
|
|
148
|
+
jaegerProcess = spawn(
|
|
149
|
+
jaegerPath,
|
|
150
|
+
['--set=receivers.otlp.protocols.grpc.endpoint=localhost:14317'],
|
|
151
|
+
{ stdio: ['ignore', jaegerLogFd, jaegerLogFd] },
|
|
152
|
+
);
|
|
153
|
+
console.log(`⏳ Waiting for Jaeger to start (PID: ${jaegerProcess.pid})...`);
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
await waitForPort(JAEGER_PORT);
|
|
157
|
+
console.log(`✅ Jaeger started successfully.`);
|
|
158
|
+
} catch (_) {
|
|
159
|
+
console.error(`🛑 Error: Jaeger failed to start on port ${JAEGER_PORT}.`);
|
|
160
|
+
if (jaegerProcess && jaegerProcess.pid) {
|
|
161
|
+
process.kill(jaegerProcess.pid, 'SIGKILL');
|
|
162
|
+
}
|
|
163
|
+
if (fileExists(JAEGER_LOG_FILE)) {
|
|
164
|
+
console.error('📄 Jaeger Log Output:');
|
|
165
|
+
console.error(fs.readFileSync(JAEGER_LOG_FILE, 'utf-8'));
|
|
166
|
+
}
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Start the primary OTEL collector
|
|
171
|
+
console.log(`🚀 Starting OTEL collector... Logs: ${OTEL_LOG_FILE}`);
|
|
172
|
+
collectorLogFd = fs.openSync(OTEL_LOG_FILE, 'a');
|
|
173
|
+
collectorProcess = spawn(otelcolPath, ['--config', OTEL_CONFIG_FILE], {
|
|
174
|
+
stdio: ['ignore', collectorLogFd, collectorLogFd],
|
|
175
|
+
});
|
|
176
|
+
console.log(
|
|
177
|
+
`⏳ Waiting for OTEL collector to start (PID: ${collectorProcess.pid})...`,
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
await waitForPort(4317);
|
|
182
|
+
console.log(`✅ OTEL collector started successfully.`);
|
|
183
|
+
} catch (_) {
|
|
184
|
+
console.error(`🛑 Error: OTEL collector failed to start on port 4317.`);
|
|
185
|
+
if (collectorProcess && collectorProcess.pid) {
|
|
186
|
+
process.kill(collectorProcess.pid, 'SIGKILL');
|
|
187
|
+
}
|
|
188
|
+
if (fileExists(OTEL_LOG_FILE)) {
|
|
189
|
+
console.error('📄 OTEL Collector Log Output:');
|
|
190
|
+
console.error(fs.readFileSync(OTEL_LOG_FILE, 'utf-8'));
|
|
191
|
+
}
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
[jaegerProcess, collectorProcess].forEach((proc) => {
|
|
196
|
+
if (proc) {
|
|
197
|
+
proc.on('error', (err) => {
|
|
198
|
+
console.error(`${proc.spawnargs[0]} process error:`, err);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
console.log(`
|
|
205
|
+
✨ Local telemetry environment is running.`);
|
|
206
|
+
console.log(
|
|
207
|
+
`
|
|
208
|
+
🔎 View traces in the Jaeger UI: http://localhost:${JAEGER_PORT}`,
|
|
209
|
+
);
|
|
210
|
+
console.log(`📊 View metrics in the logs and metrics: ${OTEL_LOG_FILE}`);
|
|
211
|
+
console.log(
|
|
212
|
+
`
|
|
213
|
+
📄 Tail logs and metrics in another terminal: tail -f ${OTEL_LOG_FILE}`,
|
|
214
|
+
);
|
|
215
|
+
console.log(`
|
|
216
|
+
Press Ctrl+C to exit.`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
main();
|