@lifeaitools/clauth 1.30.26 → 2.0.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/install.ps1 CHANGED
@@ -1,105 +1,105 @@
1
- # clauth installer - Windows
2
- # Private repo - run locally:
3
- # cd C:\Dev\clauth && git pull && .\install.ps1
4
-
5
- $ErrorActionPreference = "Stop"
6
- $REPO = "https://github.com/LIFEAI/clauth.git"
7
- $DIR = "$env:USERPROFILE\.clauth"
8
-
9
- # Check git
10
- try { git --version | Out-Null } catch {
11
- Write-Host ""
12
- Write-Host " x git is required." -ForegroundColor Red
13
- Write-Host " Install from https://git-scm.com then re-run this script."
14
- Write-Host ""
15
- exit 1
16
- }
17
-
18
- # Check Node
19
- try { node --version | Out-Null } catch {
20
- Write-Host ""
21
- Write-Host " x Node.js v18+ is required." -ForegroundColor Red
22
- Write-Host " Install from https://nodejs.org then re-run this script."
23
- Write-Host ""
24
- exit 1
25
- }
26
-
27
- # Check cloudflared (soft warning - not required for install)
28
- if (-not (Get-Command cloudflared -ErrorAction SilentlyContinue)) {
29
- Write-Host " Note: cloudflared not found. Install after setup for claude.ai web integration." -ForegroundColor Yellow
30
- Write-Host " winget install Cloudflare.cloudflared" -ForegroundColor Gray
31
- Write-Host ""
32
- }
33
-
34
- # Skip bootstrap if CLAUTH npm package is already installed globally
35
- $alreadyInstalled = $false
36
- try {
37
- $ver = & npm list -g @lifeaitools/clauth --depth=0 2>$null | Select-String "@lifeaitools/clauth"
38
- if ($ver) { $alreadyInstalled = $true }
39
- } catch { }
40
-
41
- if ($alreadyInstalled) {
42
- Write-Host " clauth already installed globally - skipping bootstrap." -ForegroundColor Green
43
- } else {
44
- # Clone or update
45
- if (Test-Path "$DIR\.git") {
46
- Write-Host " Updating clauth..."
47
- Set-Location $DIR; git pull --quiet
48
- } else {
49
- Write-Host " Cloning clauth..."
50
- git clone --quiet $REPO $DIR
51
- }
52
-
53
- # Run compiled bootstrap binary
54
- $bootstrap = "$DIR\scripts\bin\bootstrap-win.exe"
55
- if (-not (Test-Path $bootstrap)) {
56
- Write-Host " x Bootstrap binary not found at $bootstrap" -ForegroundColor Red
57
- exit 1
58
- }
59
-
60
- Set-Location $DIR
61
- & $bootstrap
62
- }
63
-
64
- # Register autostart - idempotent, runs every install/update
65
- # Primary: Task Scheduler (preferred - supports delay and OS-managed restarts)
66
- # Fallback: Startup folder shortcut (fully functional - autostart.ps1 has its own crash-recovery loop)
67
- $autostartScript = "$env:APPDATA\clauth\autostart.ps1"
68
- $taskName = "CLAUTH Daemon"
69
-
70
- if (Test-Path $autostartScript) {
71
- Write-Host ""
72
- Write-Host " Registering autostart..." -ForegroundColor Cyan
73
-
74
- $registered = $false
75
-
76
- # Try Task Scheduler first
77
- try {
78
- Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue
79
- $action = New-ScheduledTaskAction -Execute "powershell.exe" `
80
- -Argument "-WindowStyle Hidden -ExecutionPolicy Bypass -File `"$autostartScript`""
81
- $trigger = New-ScheduledTaskTrigger -AtLogOn
82
- $settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit 0 -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1)
83
- Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger `
84
- -Settings $settings -RunLevel Limited -Force -ErrorAction Stop | Out-Null
85
- Write-Host " + Task Scheduler: '$taskName' registered (triggers at logon)." -ForegroundColor Green
86
- $registered = $true
87
- } catch { }
88
-
89
- # Fallback: Startup folder - valid solution, autostart.ps1 handles crash recovery internally
90
- if (-not $registered) {
91
- $startupDir = "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup"
92
- $shortcut = "$startupDir\clauth-autostart.lnk"
93
- $wsh = New-Object -ComObject WScript.Shell
94
- $lnk = $wsh.CreateShortcut($shortcut)
95
- $lnk.TargetPath = "powershell.exe"
96
- # 15s delay baked in so profile is loaded before daemon starts
97
- $lnk.Arguments = "-WindowStyle Hidden -ExecutionPolicy Bypass -Command `"Start-Sleep 15; & '$autostartScript'`""
98
- $lnk.WorkingDirectory = "$env:APPDATA\clauth"
99
- $lnk.WindowStyle = 7
100
- $lnk.Save()
101
- Write-Host " + Autostart registered via Startup folder (15s delay, crash-recovery loop active)." -ForegroundColor Green
102
- }
1
+ # clauth installer - Windows
2
+ # Private repo - run locally:
3
+ # cd C:\Dev\clauth && git pull && .\install.ps1
4
+
5
+ $ErrorActionPreference = "Stop"
6
+ $REPO = "https://github.com/LIFEAI/clauth.git"
7
+ $DIR = "$env:USERPROFILE\.clauth"
8
+
9
+ # Check git
10
+ try { git --version | Out-Null } catch {
11
+ Write-Host ""
12
+ Write-Host " x git is required." -ForegroundColor Red
13
+ Write-Host " Install from https://git-scm.com then re-run this script."
14
+ Write-Host ""
15
+ exit 1
16
+ }
17
+
18
+ # Check Node
19
+ try { node --version | Out-Null } catch {
20
+ Write-Host ""
21
+ Write-Host " x Node.js v18+ is required." -ForegroundColor Red
22
+ Write-Host " Install from https://nodejs.org then re-run this script."
23
+ Write-Host ""
24
+ exit 1
25
+ }
26
+
27
+ # Check cloudflared (soft warning - not required for install)
28
+ if (-not (Get-Command cloudflared -ErrorAction SilentlyContinue)) {
29
+ Write-Host " Note: cloudflared not found. Install after setup for claude.ai web integration." -ForegroundColor Yellow
30
+ Write-Host " winget install Cloudflare.cloudflared" -ForegroundColor Gray
31
+ Write-Host ""
32
+ }
33
+
34
+ # Skip bootstrap if CLAUTH npm package is already installed globally
35
+ $alreadyInstalled = $false
36
+ try {
37
+ $ver = & npm list -g @lifeaitools/clauth --depth=0 2>$null | Select-String "@lifeaitools/clauth"
38
+ if ($ver) { $alreadyInstalled = $true }
39
+ } catch { }
40
+
41
+ if ($alreadyInstalled) {
42
+ Write-Host " clauth already installed globally - skipping bootstrap." -ForegroundColor Green
43
+ } else {
44
+ # Clone or update
45
+ if (Test-Path "$DIR\.git") {
46
+ Write-Host " Updating clauth..."
47
+ Set-Location $DIR; git pull --quiet
48
+ } else {
49
+ Write-Host " Cloning clauth..."
50
+ git clone --quiet $REPO $DIR
51
+ }
52
+
53
+ # Run compiled bootstrap binary
54
+ $bootstrap = "$DIR\scripts\bin\bootstrap-win.exe"
55
+ if (-not (Test-Path $bootstrap)) {
56
+ Write-Host " x Bootstrap binary not found at $bootstrap" -ForegroundColor Red
57
+ exit 1
58
+ }
59
+
60
+ Set-Location $DIR
61
+ & $bootstrap
62
+ }
63
+
64
+ # Register autostart - idempotent, runs every install/update
65
+ # Primary: Task Scheduler (preferred - supports delay and OS-managed restarts)
66
+ # Fallback: Startup folder shortcut (fully functional - autostart.ps1 has its own crash-recovery loop)
67
+ $autostartScript = "$env:APPDATA\clauth\autostart.ps1"
68
+ $taskName = "CLAUTH Daemon"
69
+
70
+ if (Test-Path $autostartScript) {
71
+ Write-Host ""
72
+ Write-Host " Registering autostart..." -ForegroundColor Cyan
73
+
74
+ $registered = $false
75
+
76
+ # Try Task Scheduler first
77
+ try {
78
+ Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue
79
+ $action = New-ScheduledTaskAction -Execute "powershell.exe" `
80
+ -Argument "-WindowStyle Hidden -ExecutionPolicy Bypass -File `"$autostartScript`""
81
+ $trigger = New-ScheduledTaskTrigger -AtLogOn
82
+ $settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit 0 -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1)
83
+ Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger `
84
+ -Settings $settings -RunLevel Limited -Force -ErrorAction Stop | Out-Null
85
+ Write-Host " + Task Scheduler: '$taskName' registered (triggers at logon)." -ForegroundColor Green
86
+ $registered = $true
87
+ } catch { }
88
+
89
+ # Fallback: Startup folder - valid solution, autostart.ps1 handles crash recovery internally
90
+ if (-not $registered) {
91
+ $startupDir = "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup"
92
+ $shortcut = "$startupDir\clauth-autostart.lnk"
93
+ $wsh = New-Object -ComObject WScript.Shell
94
+ $lnk = $wsh.CreateShortcut($shortcut)
95
+ $lnk.TargetPath = "powershell.exe"
96
+ # 15s delay baked in so profile is loaded before daemon starts
97
+ $lnk.Arguments = "-WindowStyle Hidden -ExecutionPolicy Bypass -Command `"Start-Sleep 15; & '$autostartScript'`""
98
+ $lnk.WorkingDirectory = "$env:APPDATA\clauth"
99
+ $lnk.WindowStyle = 7
100
+ $lnk.Save()
101
+ Write-Host " + Autostart registered via Startup folder (15s delay, crash-recovery loop active)." -ForegroundColor Green
102
+ }
103
103
  } else {
104
104
  Write-Host ""
105
105
  Write-Host " ! autostart.ps1 not found - skipping autostart registration." -ForegroundColor Yellow
package/install.sh CHANGED
@@ -1,49 +1,49 @@
1
- #!/usr/bin/env bash
2
- # clauth installer
3
- set -e
4
-
5
- REPO="https://github.com/LIFEAI/clauth.git"
6
- DIR="$HOME/.clauth"
7
-
8
- # Check git
9
- if ! command -v git &>/dev/null; then
10
- echo ""; echo " x git is required."
11
- echo " Install git from https://git-scm.com then re-run this script."; echo ""
12
- exit 1
13
- fi
14
-
15
- # Check Node
16
- if ! command -v node &>/dev/null; then
17
- echo ""; echo " x Node.js v18+ is required."
18
- echo " Install from https://nodejs.org then re-run this script."; echo ""
19
- exit 1
20
- fi
21
-
22
- # Check cloudflared (soft warning)
23
- if ! command -v cloudflared &>/dev/null; then
24
- echo " Note: cloudflared not found. Install after setup for claude.ai web integration."
25
- if [[ "$OSTYPE" == "darwin"* ]]; then
26
- echo " brew install cloudflare/cloudflare/cloudflared"
27
- else
28
- echo " https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/"
29
- fi
30
- echo ""
31
- fi
32
-
33
- # Clone or update
34
- if [ -d "$DIR/.git" ]; then
35
- echo " Updating clauth..."; cd "$DIR" && git pull --quiet
36
- else
37
- echo " Cloning clauth..."; git clone --quiet "$REPO" "$DIR"
38
- fi
39
-
40
- # Run compiled bootstrap
41
- UNAME=$(uname -s | tr '[:upper:]' '[:lower:]')
42
- if [[ "$UNAME" == *"darwin"* ]]; then
43
- BOOTSTRAP="$DIR/scripts/bin/bootstrap-macos"
44
- else
45
- BOOTSTRAP="$DIR/scripts/bin/bootstrap-linux"
46
- fi
47
-
48
- chmod +x "$BOOTSTRAP"
49
- cd "$DIR" && "$BOOTSTRAP"
1
+ #!/usr/bin/env bash
2
+ # clauth installer
3
+ set -e
4
+
5
+ REPO="https://github.com/LIFEAI/clauth.git"
6
+ DIR="$HOME/.clauth"
7
+
8
+ # Check git
9
+ if ! command -v git &>/dev/null; then
10
+ echo ""; echo " x git is required."
11
+ echo " Install git from https://git-scm.com then re-run this script."; echo ""
12
+ exit 1
13
+ fi
14
+
15
+ # Check Node
16
+ if ! command -v node &>/dev/null; then
17
+ echo ""; echo " x Node.js v18+ is required."
18
+ echo " Install from https://nodejs.org then re-run this script."; echo ""
19
+ exit 1
20
+ fi
21
+
22
+ # Check cloudflared (soft warning)
23
+ if ! command -v cloudflared &>/dev/null; then
24
+ echo " Note: cloudflared not found. Install after setup for claude.ai web integration."
25
+ if [[ "$OSTYPE" == "darwin"* ]]; then
26
+ echo " brew install cloudflare/cloudflare/cloudflared"
27
+ else
28
+ echo " https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/"
29
+ fi
30
+ echo ""
31
+ fi
32
+
33
+ # Clone or update
34
+ if [ -d "$DIR/.git" ]; then
35
+ echo " Updating clauth..."; cd "$DIR" && git pull --quiet
36
+ else
37
+ echo " Cloning clauth..."; git clone --quiet "$REPO" "$DIR"
38
+ fi
39
+
40
+ # Run compiled bootstrap
41
+ UNAME=$(uname -s | tr '[:upper:]' '[:lower:]')
42
+ if [[ "$UNAME" == *"darwin"* ]]; then
43
+ BOOTSTRAP="$DIR/scripts/bin/bootstrap-macos"
44
+ else
45
+ BOOTSTRAP="$DIR/scripts/bin/bootstrap-linux"
46
+ fi
47
+
48
+ chmod +x "$BOOTSTRAP"
49
+ cd "$DIR" && "$BOOTSTRAP"
package/package.json CHANGED
@@ -1,19 +1,18 @@
1
1
  {
2
2
  "name": "@lifeaitools/clauth",
3
- "version": "1.30.26",
3
+ "version": "2.0.0",
4
4
  "description": "Hardware-bound credential vault for the LIFEAI infrastructure stack",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "clauth": "./cli/index.js"
8
8
  },
9
9
  "scripts": {
10
- "build": "bash scripts/build.sh",
11
- "test": "node --test cli/commands/scrub.test.js cli/api.classify.test.js test/studio-debug.test.mjs test/dashboard-key-generator.test.mjs && node test-auth-verdict.mjs",
10
+ "build": "node scripts/build.mjs",
11
+ "test": "node --test cli/commands/scrub.test.js cli/commands/login.test.js cli/api.classify.test.js test/studio-debug.test.mjs test/dashboard-key-generator.test.mjs && node test-auth-verdict.mjs",
12
12
  "test:studio-debug": "node --test test/studio-debug.test.mjs",
13
13
  "test:agent-pool": "node test/agent-pool.test.mjs",
14
14
  "test:call-agent-10": "node test/call-agent-10-skills.test.mjs",
15
15
  "test:call-agent-guard": "node test/call-agent-guard.test.mjs",
16
- "test:tintin-settings": "node test/tintin-settings.test.mjs",
17
16
  "postinstall": "node scripts/postinstall.js",
18
17
  "worker:start": "node cli/index.js serve",
19
18
  "worker:stop": "curl -s http://127.0.0.1:52437/shutdown 2>nul || taskkill /F /IM cloudflared.exe 2>nul & exit 0",
@@ -29,7 +28,6 @@
29
28
  "node-fetch": "^3.3.2",
30
29
  "ora": "^8.1.0",
31
30
  "pm2": "^7.0.3",
32
- "regen-root": "file:../../regen-root.wt/x-claude-sv",
33
31
  "typescript": "^5.9.3"
34
32
  },
35
33
  "engines": {
@@ -55,6 +53,7 @@
55
53
  "cli/",
56
54
  "scripts/bin/",
57
55
  "scripts/bootstrap.cjs",
56
+ "scripts/build.mjs",
58
57
  "scripts/build.sh",
59
58
  "scripts/postinstall.js",
60
59
  "cli/commands/ops-install.js",
@@ -1,121 +1,121 @@
1
- // bootstrap.cjs — CommonJS, compiled to binary by pkg
2
- // Installs npm deps, links clauth, chains to: clauth install
3
- 'use strict';
4
- const { execSync, spawnSync } = require('child_process');
5
- const { join } = require('path');
6
- const ROOT = join(__dirname, '..');
7
-
8
- function run(cmd, opts) {
9
- return spawnSync(cmd, Object.assign({ shell: true, stdio: 'inherit', cwd: ROOT }, opts || {}));
10
- }
11
- function check(cmd) {
12
- try { execSync(cmd + ' --version', { stdio: 'pipe' }); return true; } catch { return false; }
13
- }
14
-
15
- console.log('\n Installing clauth runtime...\n');
16
-
17
- if (!check('git')) {
18
- console.error(' x git not found. Install from https://git-scm.com');
19
- process.exit(1);
20
- }
21
- var nodeVer = parseInt(process.version.slice(1));
22
- if (nodeVer < 18) {
23
- console.error(' x Node.js v18+ required (found ' + process.version + ')');
24
- console.error(' Install from https://nodejs.org');
25
- process.exit(1);
26
- }
27
-
28
- console.log(' -> Installing dependencies...');
29
- var inst = run('npm install --no-fund --no-audit', { stdio: ['ignore','ignore','pipe'] });
30
- if (inst.status !== 0) { console.error(' x npm install failed'); process.exit(1); }
31
- console.log(' + Dependencies ready');
32
-
33
- console.log(' -> Linking clauth command...');
34
- var lnk = run('npm link', { stdio: ['ignore','ignore','pipe'] });
35
- if (lnk.status !== 0) {
36
- var slnk = run('sudo npm link', { stdio: 'inherit' });
37
- if (slnk.status !== 0) console.warn(' ! Could not link globally — add ' + ROOT + '/node_modules/.bin to PATH');
38
- }
39
- console.log(' + clauth linked');
40
-
41
- // Check if cloudflared is installed
42
- var cfFound = false;
43
- try {
44
- execSync('cloudflared --version', { stdio: 'ignore' });
45
- cfFound = true;
46
- } catch {}
47
-
48
- if (!cfFound) {
49
- console.log('\n cloudflared not found — needed for claude.ai web integration (tunnel).');
50
-
51
- var platform = process.platform;
52
- var installCmd = null;
53
- var installLabel = null;
54
-
55
- if (platform === 'win32') {
56
- try {
57
- execSync('winget --version', { stdio: 'ignore' });
58
- installCmd = 'winget install Cloudflare.cloudflared --silent --accept-package-agreements --accept-source-agreements';
59
- installLabel = 'winget';
60
- } catch {}
61
- } else if (platform === 'darwin') {
62
- try {
63
- execSync('brew --version', { stdio: 'ignore' });
64
- installCmd = 'brew install cloudflare/cloudflare/cloudflared';
65
- installLabel = 'Homebrew';
66
- } catch {}
67
- }
68
- // Linux: no auto-install — falls through to manual instructions
69
-
70
- if (installCmd) {
71
- process.stdout.write(' Install now via ' + installLabel + '? (y/n): ');
72
- var answer = (function () {
73
- try {
74
- var buf = Buffer.alloc(3);
75
- var fd = require('fs').openSync('/dev/tty', 'r');
76
- require('fs').readSync(fd, buf, 0, 3);
77
- require('fs').closeSync(fd);
78
- return buf.toString().trim().toLowerCase();
79
- } catch {
80
- try {
81
- var result = require('child_process').spawnSync(
82
- 'powershell',
83
- ['-Command', "$k = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown'); $k.Character"],
84
- { encoding: 'utf8' }
85
- );
86
- return (result.stdout || '').trim().toLowerCase();
87
- } catch { return 'n'; }
88
- }
89
- })();
90
-
91
- if (answer === 'y') {
92
- console.log(' Installing cloudflared via ' + installLabel + '...');
93
- try {
94
- execSync(installCmd, { stdio: 'inherit' });
95
- console.log(' + cloudflared installed.');
96
- } catch (e) {
97
- console.log(' x Auto-install failed. Install manually:');
98
- console.log(' https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/');
99
- }
100
- } else {
101
- console.log(' Skipped. Install later and run: clauth tunnel setup');
102
- }
103
- } else {
104
- console.log(' Install manually:');
105
- if (platform === 'win32') {
106
- console.log(' winget install Cloudflare.cloudflared');
107
- console.log(' or: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/');
108
- } else if (platform === 'darwin') {
109
- console.log(' brew install cloudflare/cloudflare/cloudflared');
110
- console.log(' or: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/');
111
- } else {
112
- console.log(' https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/');
113
- }
114
- console.log(' Then run: clauth tunnel setup');
115
- }
116
- console.log('');
117
- }
118
-
119
- console.log('\n -> Launching clauth install...\n');
120
- var r = run('clauth install');
121
- process.exit(r.status || 0);
1
+ // bootstrap.cjs — CommonJS, compiled to binary by pkg
2
+ // Installs npm deps, links clauth, chains to: clauth install
3
+ 'use strict';
4
+ const { execSync, spawnSync } = require('child_process');
5
+ const { join } = require('path');
6
+ const ROOT = join(__dirname, '..');
7
+
8
+ function run(cmd, opts) {
9
+ return spawnSync(cmd, Object.assign({ shell: true, stdio: 'inherit', cwd: ROOT }, opts || {}));
10
+ }
11
+ function check(cmd) {
12
+ try { execSync(cmd + ' --version', { stdio: 'pipe' }); return true; } catch { return false; }
13
+ }
14
+
15
+ console.log('\n Installing clauth runtime...\n');
16
+
17
+ if (!check('git')) {
18
+ console.error(' x git not found. Install from https://git-scm.com');
19
+ process.exit(1);
20
+ }
21
+ var nodeVer = parseInt(process.version.slice(1));
22
+ if (nodeVer < 18) {
23
+ console.error(' x Node.js v18+ required (found ' + process.version + ')');
24
+ console.error(' Install from https://nodejs.org');
25
+ process.exit(1);
26
+ }
27
+
28
+ console.log(' -> Installing dependencies...');
29
+ var inst = run('npm install --no-fund --no-audit', { stdio: ['ignore','ignore','pipe'] });
30
+ if (inst.status !== 0) { console.error(' x npm install failed'); process.exit(1); }
31
+ console.log(' + Dependencies ready');
32
+
33
+ console.log(' -> Linking clauth command...');
34
+ var lnk = run('npm link', { stdio: ['ignore','ignore','pipe'] });
35
+ if (lnk.status !== 0) {
36
+ var slnk = run('sudo npm link', { stdio: 'inherit' });
37
+ if (slnk.status !== 0) console.warn(' ! Could not link globally — add ' + ROOT + '/node_modules/.bin to PATH');
38
+ }
39
+ console.log(' + clauth linked');
40
+
41
+ // Check if cloudflared is installed
42
+ var cfFound = false;
43
+ try {
44
+ execSync('cloudflared --version', { stdio: 'ignore' });
45
+ cfFound = true;
46
+ } catch {}
47
+
48
+ if (!cfFound) {
49
+ console.log('\n cloudflared not found — needed for claude.ai web integration (tunnel).');
50
+
51
+ var platform = process.platform;
52
+ var installCmd = null;
53
+ var installLabel = null;
54
+
55
+ if (platform === 'win32') {
56
+ try {
57
+ execSync('winget --version', { stdio: 'ignore' });
58
+ installCmd = 'winget install Cloudflare.cloudflared --silent --accept-package-agreements --accept-source-agreements';
59
+ installLabel = 'winget';
60
+ } catch {}
61
+ } else if (platform === 'darwin') {
62
+ try {
63
+ execSync('brew --version', { stdio: 'ignore' });
64
+ installCmd = 'brew install cloudflare/cloudflare/cloudflared';
65
+ installLabel = 'Homebrew';
66
+ } catch {}
67
+ }
68
+ // Linux: no auto-install — falls through to manual instructions
69
+
70
+ if (installCmd) {
71
+ process.stdout.write(' Install now via ' + installLabel + '? (y/n): ');
72
+ var answer = (function () {
73
+ try {
74
+ var buf = Buffer.alloc(3);
75
+ var fd = require('fs').openSync('/dev/tty', 'r');
76
+ require('fs').readSync(fd, buf, 0, 3);
77
+ require('fs').closeSync(fd);
78
+ return buf.toString().trim().toLowerCase();
79
+ } catch {
80
+ try {
81
+ var result = require('child_process').spawnSync(
82
+ 'powershell',
83
+ ['-Command', "$k = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown'); $k.Character"],
84
+ { encoding: 'utf8' }
85
+ );
86
+ return (result.stdout || '').trim().toLowerCase();
87
+ } catch { return 'n'; }
88
+ }
89
+ })();
90
+
91
+ if (answer === 'y') {
92
+ console.log(' Installing cloudflared via ' + installLabel + '...');
93
+ try {
94
+ execSync(installCmd, { stdio: 'inherit' });
95
+ console.log(' + cloudflared installed.');
96
+ } catch (e) {
97
+ console.log(' x Auto-install failed. Install manually:');
98
+ console.log(' https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/');
99
+ }
100
+ } else {
101
+ console.log(' Skipped. Install later and run: clauth tunnel setup');
102
+ }
103
+ } else {
104
+ console.log(' Install manually:');
105
+ if (platform === 'win32') {
106
+ console.log(' winget install Cloudflare.cloudflared');
107
+ console.log(' or: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/');
108
+ } else if (platform === 'darwin') {
109
+ console.log(' brew install cloudflare/cloudflare/cloudflared');
110
+ console.log(' or: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/');
111
+ } else {
112
+ console.log(' https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/');
113
+ }
114
+ console.log(' Then run: clauth tunnel setup');
115
+ }
116
+ console.log('');
117
+ }
118
+
119
+ console.log('\n -> Launching clauth install...\n');
120
+ var r = run('clauth install');
121
+ process.exit(r.status || 0);
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Regenerate bootstrap binaries from source on every supported host.
3
+ * npm's own Node process is authoritative; a separately found Git Bash on
4
+ * Windows may not expose node on PATH.
5
+ */
6
+ import { chmodSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
7
+ import { spawnSync } from "node:child_process";
8
+ import { createRequire } from "node:module";
9
+ import { dirname, join } from "node:path";
10
+ import { fileURLToPath } from "node:url";
11
+
12
+ const require = createRequire(import.meta.url);
13
+ const root = dirname(dirname(fileURLToPath(import.meta.url)));
14
+ const scripts = join(root, "scripts");
15
+ const bin = join(scripts, "bin");
16
+ const tmp = join(bin, "tmp");
17
+ const obfuscated = join(scripts, "bootstrap.ob.cjs");
18
+
19
+ try {
20
+ process.stdout.write("→ Obfuscating bootstrap.cjs...\n");
21
+ const obfuscator = require("javascript-obfuscator");
22
+ const source = readFileSync(join(scripts, "bootstrap.cjs"), "utf8");
23
+ const output = obfuscator.obfuscate(source, {
24
+ compact: true,
25
+ controlFlowFlattening: true,
26
+ controlFlowFlatteningThreshold: 0.75,
27
+ deadCodeInjection: true,
28
+ deadCodeInjectionThreshold: 0.4,
29
+ identifierNamesGenerator: "hexadecimal",
30
+ rotateStringArray: true,
31
+ shuffleStringArray: true,
32
+ splitStrings: true,
33
+ splitStringsChunkLength: 8,
34
+ stringArray: true,
35
+ stringArrayEncoding: ["base64"],
36
+ stringArrayThreshold: 0.85,
37
+ transformObjectKeys: true,
38
+ target: "node",
39
+ });
40
+ writeFileSync(obfuscated, output.getObfuscatedCode());
41
+ process.stdout.write(" ✓ Obfuscated\n→ Compiling binaries...\n");
42
+ mkdirSync(tmp, { recursive: true });
43
+ const compile = spawnSync(
44
+ process.platform === "win32" ? "npx.cmd" : "npx",
45
+ ["pkg", obfuscated, "--targets", "node18-win-x64,node18-linux-x64,node18-macos-x64", "--out-path", tmp],
46
+ // Windows `.cmd` shims require cmd.exe; inputs are constant paths/targets.
47
+ { cwd: root, encoding: "utf8", shell: process.platform === "win32", windowsHide: true },
48
+ );
49
+ const outputLog = `${compile.stdout ?? ""}${compile.stderr ?? ""}`.split(/\r?\n/).filter((line) => line && !line.includes("Warning")).join("\n");
50
+ if (outputLog) process.stdout.write(`${outputLog}\n`);
51
+ if (compile.error || compile.status !== 0) throw compile.error ?? new Error(`pkg exited ${compile.status ?? "unknown"}`);
52
+ for (const [from, to] of [["bootstrap.ob-linux", "bootstrap-linux"], ["bootstrap.ob-macos", "bootstrap-macos"], ["bootstrap.ob-win.exe", "bootstrap-win.exe"]]) {
53
+ const sourcePath = join(tmp, from);
54
+ if (!existsSync(sourcePath)) throw new Error(`pkg did not produce ${from}`);
55
+ renameSync(sourcePath, join(bin, to));
56
+ }
57
+ for (const filename of ["bootstrap-linux", "bootstrap-macos"]) chmodSync(join(bin, filename), 0o755);
58
+ rmSync(tmp, { recursive: true, force: true });
59
+ rmSync(obfuscated, { force: true });
60
+ process.stdout.write(`${readdirSync(bin).join("\n")}\n✓ Build complete\n`);
61
+ } catch (error) {
62
+ rmSync(tmp, { recursive: true, force: true });
63
+ rmSync(obfuscated, { force: true });
64
+ process.stderr.write(`Build failed: ${error instanceof Error ? error.message : String(error)}\n`);
65
+ process.exitCode = 1;
66
+ }