@lifeaitools/clauth 1.9.2 → 1.16.9
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/.clauth-skill/SKILL.md +80 -22
- package/README.md +85 -42
- package/cli/api.js +47 -36
- package/cli/assets/codevelop/launcher-active.cmd.template +20 -20
- package/cli/assets/codevelop/launcher-static.cmd.template +7 -7
- package/cli/assets/codevelop/windows-terminal.profiles.json +48 -48
- package/cli/assets/watchdog.ps1 +42 -42
- package/cli/commands/agent-cron.js +396 -0
- package/cli/commands/agent-pool.js +1745 -0
- package/cli/commands/codevelop.js +1190 -1190
- package/cli/commands/doctor.js +302 -302
- package/cli/commands/install.js +10 -10
- package/cli/commands/invite.js +175 -175
- package/cli/commands/join.js +179 -179
- package/cli/commands/npm.js +182 -182
- package/cli/commands/scrub.js +205 -109
- package/cli/commands/scrub.test.js +115 -0
- package/cli/commands/serve.js +11716 -10733
- package/cli/commands/watchdog.js +209 -209
- package/cli/conf-path.js +21 -21
- package/cli/index.js +1089 -1085
- package/cli/lib/fs-git.js +282 -282
- package/cli/recovery.js +101 -101
- package/cli/studio-debug.js +487 -424
- package/cli/watchdog-registry.js +209 -209
- package/cli/watchdog-registry.test.js +89 -89
- package/install.ps1 +21 -21
- package/package.json +65 -61
- package/scripts/postinstall.js +164 -164
- package/supabase/migrations/001_clauth_schema.sql +12 -12
- package/supabase/migrations/003_clauth_config.sql +13 -13
- package/supabase/migrations/003_machine_enrollments.sql +39 -39
package/package.json
CHANGED
|
@@ -1,61 +1,65 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@lifeaitools/clauth",
|
|
3
|
-
"version": "1.9
|
|
4
|
-
"description": "Hardware-bound credential vault for the LIFEAI infrastructure stack",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"clauth": "./cli/index.js"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"build": "bash scripts/build.sh",
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
".
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@lifeaitools/clauth",
|
|
3
|
+
"version": "1.16.9",
|
|
4
|
+
"description": "Hardware-bound credential vault for the LIFEAI infrastructure stack",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"clauth": "./cli/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "bash scripts/build.sh",
|
|
11
|
+
"test": "node --test cli/commands/scrub.test.js && node test-auth-verdict.mjs",
|
|
12
|
+
"test:agent-pool": "node test/agent-pool.test.mjs",
|
|
13
|
+
"test:call-agent-10": "node test/call-agent-10-skills.test.mjs",
|
|
14
|
+
"test:call-agent-guard": "node test/call-agent-guard.test.mjs",
|
|
15
|
+
"postinstall": "node scripts/postinstall.js",
|
|
16
|
+
"worker:start": "node cli/index.js serve",
|
|
17
|
+
"worker:stop": "curl -s http://127.0.0.1:52437/shutdown 2>nul || taskkill /F /IM cloudflared.exe 2>nul & exit 0",
|
|
18
|
+
"worker:restart": "npm run worker:stop && timeout /t 3 /nobreak >nul && npm run worker:start"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"chalk": "^5.3.0",
|
|
22
|
+
"commander": "^12.1.0",
|
|
23
|
+
"conf": "^13.0.0",
|
|
24
|
+
"inquirer": "^10.1.0",
|
|
25
|
+
"node-fetch": "^3.3.2",
|
|
26
|
+
"ora": "^8.1.0",
|
|
27
|
+
"@vscode/ripgrep": "^1.15.9",
|
|
28
|
+
"fast-glob": "^3.3.2"
|
|
29
|
+
},
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=18.0.0"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"lifeai",
|
|
35
|
+
"credentials",
|
|
36
|
+
"vault",
|
|
37
|
+
"cli",
|
|
38
|
+
"prt"
|
|
39
|
+
],
|
|
40
|
+
"author": "Dave Ladouceur <dave@life.ai>",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "https://github.com/LIFEAI/clauth.git"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"javascript-obfuscator": "^5.3.0"
|
|
48
|
+
},
|
|
49
|
+
"files": [
|
|
50
|
+
"cli/",
|
|
51
|
+
"scripts/bin/",
|
|
52
|
+
"scripts/bootstrap.cjs",
|
|
53
|
+
"scripts/build.sh",
|
|
54
|
+
"scripts/postinstall.js",
|
|
55
|
+
"supabase/",
|
|
56
|
+
".clauth-skill/",
|
|
57
|
+
"install.sh",
|
|
58
|
+
"install.ps1",
|
|
59
|
+
"README.md"
|
|
60
|
+
],
|
|
61
|
+
"publishConfig": {
|
|
62
|
+
"access": "public"
|
|
63
|
+
},
|
|
64
|
+
"homepage": "https://github.com/LIFEAI/clauth"
|
|
65
|
+
}
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,164 +1,164 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// scripts/postinstall.js
|
|
3
|
-
// Runs after npm install -g @lifeaitools/clauth
|
|
4
|
-
// On Windows: writes watchdog.ps1 to %APPDATA%\clauth\ and registers
|
|
5
|
-
// the Task Scheduler job via UAC elevation.
|
|
6
|
-
|
|
7
|
-
import fs from "fs";
|
|
8
|
-
import path from "path";
|
|
9
|
-
import os from "os";
|
|
10
|
-
import { fileURLToPath } from "url";
|
|
11
|
-
import { spawnSync } from "child_process";
|
|
12
|
-
|
|
13
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
|
-
const APPDATA = process.env.APPDATA || path.join(os.homedir(), "AppData", "Roaming");
|
|
15
|
-
const CLAUTH_DIR = path.join(APPDATA, "clauth");
|
|
16
|
-
const DEST_PS1 = path.join(CLAUTH_DIR, "watchdog.ps1");
|
|
17
|
-
const SOURCE_PS1 = path.join(__dirname, "..", "cli", "assets", "watchdog.ps1");
|
|
18
|
-
const PS_EXE = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe";
|
|
19
|
-
const TASK_NAME = "ClautWatchdog";
|
|
20
|
-
|
|
21
|
-
const CONFIG_DIR = os.platform() === "win32"
|
|
22
|
-
? path.join(APPDATA, "clauth-nodejs", "Config")
|
|
23
|
-
: path.join(os.homedir(), ".config", "clauth-nodejs");
|
|
24
|
-
|
|
25
|
-
let version = "1.0.0";
|
|
26
|
-
try {
|
|
27
|
-
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "package.json"), "utf8"));
|
|
28
|
-
version = pkg.version;
|
|
29
|
-
} catch {}
|
|
30
|
-
|
|
31
|
-
// ----------------------------------------------------------------
|
|
32
|
-
// Watchdog helpers (Windows only)
|
|
33
|
-
// ----------------------------------------------------------------
|
|
34
|
-
|
|
35
|
-
function writeWatchdogScript() {
|
|
36
|
-
try {
|
|
37
|
-
fs.mkdirSync(CLAUTH_DIR, { recursive: true });
|
|
38
|
-
fs.copyFileSync(SOURCE_PS1, DEST_PS1);
|
|
39
|
-
return true;
|
|
40
|
-
} catch (err) {
|
|
41
|
-
console.log(` ! Could not write watchdog script: ${err.message}`);
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function isWatchdogRegistered() {
|
|
47
|
-
try {
|
|
48
|
-
const r = spawnSync(PS_EXE, [
|
|
49
|
-
"-NoProfile", "-Command",
|
|
50
|
-
`(Get-ScheduledTask -TaskName '${TASK_NAME}' -ErrorAction SilentlyContinue) -ne $null`,
|
|
51
|
-
], { encoding: "utf8", stdio: ["pipe","pipe","pipe"], timeout: 5000 });
|
|
52
|
-
return (r.stdout || "").trim().toLowerCase() === "true";
|
|
53
|
-
} catch { return false; }
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function registerWatchdog() {
|
|
57
|
-
const escaped = DEST_PS1.replace(/'/g, "''");
|
|
58
|
-
const psCmd = [
|
|
59
|
-
`$a = New-ScheduledTaskAction -Execute 'powershell.exe'`,
|
|
60
|
-
` -Argument '-NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File \\"${escaped}\\"';`,
|
|
61
|
-
`$t = New-ScheduledTaskTrigger -AtLogOn;`,
|
|
62
|
-
`$s = New-ScheduledTaskSettingsSet -ExecutionTimeLimit 0 -RestartCount 3`,
|
|
63
|
-
` -RestartInterval (New-TimeSpan -Minutes 1) -MultipleInstances IgnoreNew;`,
|
|
64
|
-
`Unregister-ScheduledTask -TaskName '${TASK_NAME}' -Confirm:$false -ErrorAction SilentlyContinue;`,
|
|
65
|
-
`Register-ScheduledTask -TaskName '${TASK_NAME}' -Action $a -Trigger $t`,
|
|
66
|
-
` -Settings $s -RunLevel Highest -Description 'clauth daemon watchdog';`,
|
|
67
|
-
].join(" ");
|
|
68
|
-
|
|
69
|
-
// Try direct first (works if already running as Administrator)
|
|
70
|
-
const direct = spawnSync(PS_EXE, [
|
|
71
|
-
"-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", psCmd,
|
|
72
|
-
], { encoding: "utf8", stdio: ["pipe","pipe","pipe"], timeout: 10000 });
|
|
73
|
-
|
|
74
|
-
if (direct.status === 0) return "ok";
|
|
75
|
-
|
|
76
|
-
// Trigger UAC elevation — opens the Windows approval dialog
|
|
77
|
-
const inner = psCmd.replace(/"/g, '\\"');
|
|
78
|
-
const elevated = spawnSync(PS_EXE, [
|
|
79
|
-
"-NoProfile", "-Command",
|
|
80
|
-
`Start-Process '${PS_EXE}' -Verb RunAs -Wait -ArgumentList '-NoProfile -ExecutionPolicy Bypass -Command "${inner}"'`,
|
|
81
|
-
], { stdio: "inherit", encoding: "utf8", timeout: 60000 });
|
|
82
|
-
|
|
83
|
-
return elevated.status === 0 ? "ok" : "denied";
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function startWatchdog() {
|
|
87
|
-
spawnSync(PS_EXE, [
|
|
88
|
-
"-NoProfile", "-Command",
|
|
89
|
-
`Start-ScheduledTask -TaskName '${TASK_NAME}' -ErrorAction SilentlyContinue`,
|
|
90
|
-
], { stdio: "pipe", timeout: 5000 });
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function installCodevelopTerminalProfiles() {
|
|
94
|
-
const cli = path.join(__dirname, "..", "cli", "index.js");
|
|
95
|
-
const result = spawnSync(process.execPath, [
|
|
96
|
-
cli,
|
|
97
|
-
"codevelop",
|
|
98
|
-
"install-terminal",
|
|
99
|
-
"--repo",
|
|
100
|
-
"C:\\Dev\\regen-root",
|
|
101
|
-
], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], timeout: 10000 });
|
|
102
|
-
|
|
103
|
-
if (result.status === 0) {
|
|
104
|
-
console.log(" ✓ Co-development Windows Terminal profiles installed");
|
|
105
|
-
} else {
|
|
106
|
-
const msg = (result.stderr || result.stdout || "").trim();
|
|
107
|
-
console.log(` ! Co-development terminal profile install skipped${msg ? `: ${msg}` : ""}`);
|
|
108
|
-
console.log(" Install later with: clauth codevelop install-terminal --repo C:\\Dev\\regen-root");
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// ----------------------------------------------------------------
|
|
113
|
-
// Main
|
|
114
|
-
// ----------------------------------------------------------------
|
|
115
|
-
|
|
116
|
-
async function main() {
|
|
117
|
-
const configPath = path.join(CONFIG_DIR, "config.json");
|
|
118
|
-
const isUpgrade = fs.existsSync(configPath);
|
|
119
|
-
|
|
120
|
-
if (isUpgrade) {
|
|
121
|
-
console.log(`\n \u2713 clauth upgraded to v${version}`);
|
|
122
|
-
console.log(` \u2713 Config preserved at ${CONFIG_DIR}`);
|
|
123
|
-
try {
|
|
124
|
-
const controller = new AbortController();
|
|
125
|
-
const to = setTimeout(() => controller.abort(), 2000);
|
|
126
|
-
const res = await fetch("http://127.0.0.1:52437/ping", { signal: controller.signal });
|
|
127
|
-
clearTimeout(to);
|
|
128
|
-
if (res.ok) console.log(" \u21BB Daemon running \u2014 restart: clauth serve restart");
|
|
129
|
-
} catch {
|
|
130
|
-
console.log(" \u25CB Daemon not running");
|
|
131
|
-
}
|
|
132
|
-
} else {
|
|
133
|
-
console.log(`\n Welcome to clauth v${version}!`);
|
|
134
|
-
console.log(" Run 'clauth install' to set up your vault");
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Windows: register watchdog on fresh install; refresh script on upgrade
|
|
138
|
-
if (os.platform() === "win32") {
|
|
139
|
-
const registered = isWatchdogRegistered();
|
|
140
|
-
if (!registered) {
|
|
141
|
-
console.log("\n Setting up auto-restart watchdog...");
|
|
142
|
-
console.log(" Windows will ask for administrator approval \u2014 please click Yes.\n");
|
|
143
|
-
if (writeWatchdogScript()) {
|
|
144
|
-
const result = registerWatchdog();
|
|
145
|
-
if (result === "ok") {
|
|
146
|
-
startWatchdog();
|
|
147
|
-
console.log(" \u2713 Watchdog registered and started (Task: ClautWatchdog)");
|
|
148
|
-
console.log(` \u2713 Script: ${DEST_PS1}`);
|
|
149
|
-
} else {
|
|
150
|
-
console.log(" ! Watchdog registration skipped (approval denied).");
|
|
151
|
-
console.log(" Install later with: clauth watchdog install");
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
} else {
|
|
155
|
-
writeWatchdogScript(); // refresh script on upgrade
|
|
156
|
-
console.log(" \u2713 Watchdog script updated");
|
|
157
|
-
}
|
|
158
|
-
installCodevelopTerminalProfiles();
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
console.log(" Run 'clauth doctor' to verify installation\n");
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
main().catch(() => {});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// scripts/postinstall.js
|
|
3
|
+
// Runs after npm install -g @lifeaitools/clauth
|
|
4
|
+
// On Windows: writes watchdog.ps1 to %APPDATA%\clauth\ and registers
|
|
5
|
+
// the Task Scheduler job via UAC elevation.
|
|
6
|
+
|
|
7
|
+
import fs from "fs";
|
|
8
|
+
import path from "path";
|
|
9
|
+
import os from "os";
|
|
10
|
+
import { fileURLToPath } from "url";
|
|
11
|
+
import { spawnSync } from "child_process";
|
|
12
|
+
|
|
13
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const APPDATA = process.env.APPDATA || path.join(os.homedir(), "AppData", "Roaming");
|
|
15
|
+
const CLAUTH_DIR = path.join(APPDATA, "clauth");
|
|
16
|
+
const DEST_PS1 = path.join(CLAUTH_DIR, "watchdog.ps1");
|
|
17
|
+
const SOURCE_PS1 = path.join(__dirname, "..", "cli", "assets", "watchdog.ps1");
|
|
18
|
+
const PS_EXE = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe";
|
|
19
|
+
const TASK_NAME = "ClautWatchdog";
|
|
20
|
+
|
|
21
|
+
const CONFIG_DIR = os.platform() === "win32"
|
|
22
|
+
? path.join(APPDATA, "clauth-nodejs", "Config")
|
|
23
|
+
: path.join(os.homedir(), ".config", "clauth-nodejs");
|
|
24
|
+
|
|
25
|
+
let version = "1.0.0";
|
|
26
|
+
try {
|
|
27
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "package.json"), "utf8"));
|
|
28
|
+
version = pkg.version;
|
|
29
|
+
} catch {}
|
|
30
|
+
|
|
31
|
+
// ----------------------------------------------------------------
|
|
32
|
+
// Watchdog helpers (Windows only)
|
|
33
|
+
// ----------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
function writeWatchdogScript() {
|
|
36
|
+
try {
|
|
37
|
+
fs.mkdirSync(CLAUTH_DIR, { recursive: true });
|
|
38
|
+
fs.copyFileSync(SOURCE_PS1, DEST_PS1);
|
|
39
|
+
return true;
|
|
40
|
+
} catch (err) {
|
|
41
|
+
console.log(` ! Could not write watchdog script: ${err.message}`);
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function isWatchdogRegistered() {
|
|
47
|
+
try {
|
|
48
|
+
const r = spawnSync(PS_EXE, [
|
|
49
|
+
"-NoProfile", "-Command",
|
|
50
|
+
`(Get-ScheduledTask -TaskName '${TASK_NAME}' -ErrorAction SilentlyContinue) -ne $null`,
|
|
51
|
+
], { encoding: "utf8", stdio: ["pipe","pipe","pipe"], timeout: 5000 });
|
|
52
|
+
return (r.stdout || "").trim().toLowerCase() === "true";
|
|
53
|
+
} catch { return false; }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function registerWatchdog() {
|
|
57
|
+
const escaped = DEST_PS1.replace(/'/g, "''");
|
|
58
|
+
const psCmd = [
|
|
59
|
+
`$a = New-ScheduledTaskAction -Execute 'powershell.exe'`,
|
|
60
|
+
` -Argument '-NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File \\"${escaped}\\"';`,
|
|
61
|
+
`$t = New-ScheduledTaskTrigger -AtLogOn;`,
|
|
62
|
+
`$s = New-ScheduledTaskSettingsSet -ExecutionTimeLimit 0 -RestartCount 3`,
|
|
63
|
+
` -RestartInterval (New-TimeSpan -Minutes 1) -MultipleInstances IgnoreNew;`,
|
|
64
|
+
`Unregister-ScheduledTask -TaskName '${TASK_NAME}' -Confirm:$false -ErrorAction SilentlyContinue;`,
|
|
65
|
+
`Register-ScheduledTask -TaskName '${TASK_NAME}' -Action $a -Trigger $t`,
|
|
66
|
+
` -Settings $s -RunLevel Highest -Description 'clauth daemon watchdog';`,
|
|
67
|
+
].join(" ");
|
|
68
|
+
|
|
69
|
+
// Try direct first (works if already running as Administrator)
|
|
70
|
+
const direct = spawnSync(PS_EXE, [
|
|
71
|
+
"-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", psCmd,
|
|
72
|
+
], { encoding: "utf8", stdio: ["pipe","pipe","pipe"], timeout: 10000 });
|
|
73
|
+
|
|
74
|
+
if (direct.status === 0) return "ok";
|
|
75
|
+
|
|
76
|
+
// Trigger UAC elevation — opens the Windows approval dialog
|
|
77
|
+
const inner = psCmd.replace(/"/g, '\\"');
|
|
78
|
+
const elevated = spawnSync(PS_EXE, [
|
|
79
|
+
"-NoProfile", "-Command",
|
|
80
|
+
`Start-Process '${PS_EXE}' -Verb RunAs -Wait -ArgumentList '-NoProfile -ExecutionPolicy Bypass -Command "${inner}"'`,
|
|
81
|
+
], { stdio: "inherit", encoding: "utf8", timeout: 60000 });
|
|
82
|
+
|
|
83
|
+
return elevated.status === 0 ? "ok" : "denied";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function startWatchdog() {
|
|
87
|
+
spawnSync(PS_EXE, [
|
|
88
|
+
"-NoProfile", "-Command",
|
|
89
|
+
`Start-ScheduledTask -TaskName '${TASK_NAME}' -ErrorAction SilentlyContinue`,
|
|
90
|
+
], { stdio: "pipe", timeout: 5000 });
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function installCodevelopTerminalProfiles() {
|
|
94
|
+
const cli = path.join(__dirname, "..", "cli", "index.js");
|
|
95
|
+
const result = spawnSync(process.execPath, [
|
|
96
|
+
cli,
|
|
97
|
+
"codevelop",
|
|
98
|
+
"install-terminal",
|
|
99
|
+
"--repo",
|
|
100
|
+
"C:\\Dev\\regen-root",
|
|
101
|
+
], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], timeout: 10000 });
|
|
102
|
+
|
|
103
|
+
if (result.status === 0) {
|
|
104
|
+
console.log(" ✓ Co-development Windows Terminal profiles installed");
|
|
105
|
+
} else {
|
|
106
|
+
const msg = (result.stderr || result.stdout || "").trim();
|
|
107
|
+
console.log(` ! Co-development terminal profile install skipped${msg ? `: ${msg}` : ""}`);
|
|
108
|
+
console.log(" Install later with: clauth codevelop install-terminal --repo C:\\Dev\\regen-root");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ----------------------------------------------------------------
|
|
113
|
+
// Main
|
|
114
|
+
// ----------------------------------------------------------------
|
|
115
|
+
|
|
116
|
+
async function main() {
|
|
117
|
+
const configPath = path.join(CONFIG_DIR, "config.json");
|
|
118
|
+
const isUpgrade = fs.existsSync(configPath);
|
|
119
|
+
|
|
120
|
+
if (isUpgrade) {
|
|
121
|
+
console.log(`\n \u2713 clauth upgraded to v${version}`);
|
|
122
|
+
console.log(` \u2713 Config preserved at ${CONFIG_DIR}`);
|
|
123
|
+
try {
|
|
124
|
+
const controller = new AbortController();
|
|
125
|
+
const to = setTimeout(() => controller.abort(), 2000);
|
|
126
|
+
const res = await fetch("http://127.0.0.1:52437/ping", { signal: controller.signal });
|
|
127
|
+
clearTimeout(to);
|
|
128
|
+
if (res.ok) console.log(" \u21BB Daemon running \u2014 restart: clauth serve restart");
|
|
129
|
+
} catch {
|
|
130
|
+
console.log(" \u25CB Daemon not running");
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
console.log(`\n Welcome to clauth v${version}!`);
|
|
134
|
+
console.log(" Run 'clauth install' to set up your vault");
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Windows: register watchdog on fresh install; refresh script on upgrade
|
|
138
|
+
if (os.platform() === "win32") {
|
|
139
|
+
const registered = isWatchdogRegistered();
|
|
140
|
+
if (!registered) {
|
|
141
|
+
console.log("\n Setting up auto-restart watchdog...");
|
|
142
|
+
console.log(" Windows will ask for administrator approval \u2014 please click Yes.\n");
|
|
143
|
+
if (writeWatchdogScript()) {
|
|
144
|
+
const result = registerWatchdog();
|
|
145
|
+
if (result === "ok") {
|
|
146
|
+
startWatchdog();
|
|
147
|
+
console.log(" \u2713 Watchdog registered and started (Task: ClautWatchdog)");
|
|
148
|
+
console.log(` \u2713 Script: ${DEST_PS1}`);
|
|
149
|
+
} else {
|
|
150
|
+
console.log(" ! Watchdog registration skipped (approval denied).");
|
|
151
|
+
console.log(" Install later with: clauth watchdog install");
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
writeWatchdogScript(); // refresh script on upgrade
|
|
156
|
+
console.log(" \u2713 Watchdog script updated");
|
|
157
|
+
}
|
|
158
|
+
installCodevelopTerminalProfiles();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
console.log(" Run 'clauth doctor' to verify installation\n");
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
main().catch(() => {});
|
|
@@ -27,18 +27,18 @@ create table if not exists public.clauth_services (
|
|
|
27
27
|
-- ============================================================
|
|
28
28
|
-- Machine Registry (hardware fingerprints — hashed only)
|
|
29
29
|
-- ============================================================
|
|
30
|
-
create table if not exists public.clauth_machines (
|
|
31
|
-
id uuid primary key default gen_random_uuid(),
|
|
32
|
-
install_id text not null default 'default', -- logical vault install / owner group
|
|
33
|
-
machine_hash text not null unique, -- SHA256(machine_id + os_install_id)
|
|
34
|
-
label text, -- e.g. 'Dave-Desktop-Win11'
|
|
35
|
-
hmac_seed_hash text not null, -- SHA256 of the HMAC seed stored in vault
|
|
36
|
-
enabled boolean not null default true,
|
|
37
|
-
fail_count integer not null default 0,
|
|
38
|
-
locked boolean not null default false,
|
|
39
|
-
created_at timestamptz not null default now(),
|
|
40
|
-
last_seen timestamptz
|
|
41
|
-
);
|
|
30
|
+
create table if not exists public.clauth_machines (
|
|
31
|
+
id uuid primary key default gen_random_uuid(),
|
|
32
|
+
install_id text not null default 'default', -- logical vault install / owner group
|
|
33
|
+
machine_hash text not null unique, -- SHA256(machine_id + os_install_id)
|
|
34
|
+
label text, -- e.g. 'Dave-Desktop-Win11'
|
|
35
|
+
hmac_seed_hash text not null, -- SHA256 of the HMAC seed stored in vault
|
|
36
|
+
enabled boolean not null default true,
|
|
37
|
+
fail_count integer not null default 0,
|
|
38
|
+
locked boolean not null default false,
|
|
39
|
+
created_at timestamptz not null default now(),
|
|
40
|
+
last_seen timestamptz
|
|
41
|
+
);
|
|
42
42
|
|
|
43
43
|
-- ============================================================
|
|
44
44
|
-- Audit Log
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
-- clauth_config: key/value store for daemon configuration
|
|
2
|
-
-- Used to persist tunnel hostname and other daemon settings
|
|
3
|
-
CREATE TABLE IF NOT EXISTS clauth_config (
|
|
4
|
-
key text PRIMARY KEY,
|
|
5
|
-
value jsonb NOT NULL,
|
|
6
|
-
updated_at timestamptz DEFAULT now()
|
|
7
|
-
);
|
|
8
|
-
|
|
9
|
-
-- RLS: only service role can access (same pattern as other clauth tables)
|
|
10
|
-
ALTER TABLE clauth_config ENABLE ROW LEVEL SECURITY;
|
|
11
|
-
|
|
12
|
-
-- Seed: no tunnel by default (user must run clauth tunnel setup)
|
|
13
|
-
-- INSERT INTO clauth_config (key, value) VALUES ('tunnel_hostname', 'null');
|
|
1
|
+
-- clauth_config: key/value store for daemon configuration
|
|
2
|
+
-- Used to persist tunnel hostname and other daemon settings
|
|
3
|
+
CREATE TABLE IF NOT EXISTS clauth_config (
|
|
4
|
+
key text PRIMARY KEY,
|
|
5
|
+
value jsonb NOT NULL,
|
|
6
|
+
updated_at timestamptz DEFAULT now()
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
-- RLS: only service role can access (same pattern as other clauth tables)
|
|
10
|
+
ALTER TABLE clauth_config ENABLE ROW LEVEL SECURITY;
|
|
11
|
+
|
|
12
|
+
-- Seed: no tunnel by default (user must run clauth tunnel setup)
|
|
13
|
+
-- INSERT INTO clauth_config (key, value) VALUES ('tunnel_hostname', 'null');
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
-- ============================================================
|
|
2
|
-
-- clauth machine enrollment
|
|
3
|
-
-- Migration: 003_machine_enrollments.sql
|
|
4
|
-
-- ============================================================
|
|
5
|
-
|
|
6
|
-
alter table public.clauth_machines
|
|
7
|
-
add column if not exists install_id text not null default 'default';
|
|
8
|
-
|
|
9
|
-
create index if not exists clauth_machines_install_id_idx
|
|
10
|
-
on public.clauth_machines (install_id);
|
|
11
|
-
|
|
12
|
-
create table if not exists public.clauth_machine_enrollments (
|
|
13
|
-
id uuid primary key default gen_random_uuid(),
|
|
14
|
-
install_id text not null default 'default',
|
|
15
|
-
token_hash text not null unique,
|
|
16
|
-
label text,
|
|
17
|
-
created_by_machine_hash text not null references public.clauth_machines(machine_hash) on delete cascade,
|
|
18
|
-
redeemed_by_machine_hash text references public.clauth_machines(machine_hash) on delete set null,
|
|
19
|
-
expires_at timestamptz not null,
|
|
20
|
-
consumed_at timestamptz,
|
|
21
|
-
created_at timestamptz not null default now()
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
create index if not exists clauth_machine_enrollments_install_idx
|
|
25
|
-
on public.clauth_machine_enrollments (install_id, expires_at);
|
|
26
|
-
|
|
27
|
-
alter table public.clauth_machine_enrollments enable row level security;
|
|
28
|
-
|
|
29
|
-
do $$ begin
|
|
30
|
-
if not exists (
|
|
31
|
-
select 1
|
|
32
|
-
from pg_policies
|
|
33
|
-
where policyname = 'no_anon_machine_enrollments'
|
|
34
|
-
and tablename = 'clauth_machine_enrollments'
|
|
35
|
-
) then
|
|
36
|
-
create policy "no_anon_machine_enrollments"
|
|
37
|
-
on public.clauth_machine_enrollments for all using (false);
|
|
38
|
-
end if;
|
|
39
|
-
end $$;
|
|
1
|
+
-- ============================================================
|
|
2
|
+
-- clauth machine enrollment
|
|
3
|
+
-- Migration: 003_machine_enrollments.sql
|
|
4
|
+
-- ============================================================
|
|
5
|
+
|
|
6
|
+
alter table public.clauth_machines
|
|
7
|
+
add column if not exists install_id text not null default 'default';
|
|
8
|
+
|
|
9
|
+
create index if not exists clauth_machines_install_id_idx
|
|
10
|
+
on public.clauth_machines (install_id);
|
|
11
|
+
|
|
12
|
+
create table if not exists public.clauth_machine_enrollments (
|
|
13
|
+
id uuid primary key default gen_random_uuid(),
|
|
14
|
+
install_id text not null default 'default',
|
|
15
|
+
token_hash text not null unique,
|
|
16
|
+
label text,
|
|
17
|
+
created_by_machine_hash text not null references public.clauth_machines(machine_hash) on delete cascade,
|
|
18
|
+
redeemed_by_machine_hash text references public.clauth_machines(machine_hash) on delete set null,
|
|
19
|
+
expires_at timestamptz not null,
|
|
20
|
+
consumed_at timestamptz,
|
|
21
|
+
created_at timestamptz not null default now()
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
create index if not exists clauth_machine_enrollments_install_idx
|
|
25
|
+
on public.clauth_machine_enrollments (install_id, expires_at);
|
|
26
|
+
|
|
27
|
+
alter table public.clauth_machine_enrollments enable row level security;
|
|
28
|
+
|
|
29
|
+
do $$ begin
|
|
30
|
+
if not exists (
|
|
31
|
+
select 1
|
|
32
|
+
from pg_policies
|
|
33
|
+
where policyname = 'no_anon_machine_enrollments'
|
|
34
|
+
and tablename = 'clauth_machine_enrollments'
|
|
35
|
+
) then
|
|
36
|
+
create policy "no_anon_machine_enrollments"
|
|
37
|
+
on public.clauth_machine_enrollments for all using (false);
|
|
38
|
+
end if;
|
|
39
|
+
end $$;
|