@lifeaitools/clauth 1.17.0 → 1.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/commands/serve.js +88 -6
- package/package.json +65 -65
package/cli/commands/serve.js
CHANGED
|
@@ -4657,6 +4657,7 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
|
|
|
4657
4657
|
detached: true,
|
|
4658
4658
|
stdio: ["ignore", out, out],
|
|
4659
4659
|
env: { ...process.env, __CLAUTH_DAEMON: "1" },
|
|
4660
|
+
windowsHide: true,
|
|
4660
4661
|
});
|
|
4661
4662
|
child.unref();
|
|
4662
4663
|
stopTunnel();
|
|
@@ -5412,6 +5413,7 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
|
|
|
5412
5413
|
detached: true,
|
|
5413
5414
|
stdio: ["ignore", out, out],
|
|
5414
5415
|
env: childEnv,
|
|
5416
|
+
windowsHide: true,
|
|
5415
5417
|
});
|
|
5416
5418
|
child.unref();
|
|
5417
5419
|
|
|
@@ -6341,7 +6343,7 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
|
|
|
6341
6343
|
const sendEvt = (data) => res.write(`data: ${JSON.stringify(data)}\n\n`);
|
|
6342
6344
|
try {
|
|
6343
6345
|
const { spawn } = await import("child_process");
|
|
6344
|
-
const proc = spawn("cloudflared", ["tunnel", "login"], { stdio: ["ignore","pipe","pipe"] });
|
|
6346
|
+
const proc = spawn("cloudflared", ["tunnel", "login"], { stdio: ["ignore","pipe","pipe"], windowsHide: true });
|
|
6345
6347
|
proc.stdout.on("data", d => d.toString().split("\n").forEach(l => l.trim() && sendEvt({ line: l })));
|
|
6346
6348
|
proc.stderr.on("data", d => d.toString().split("\n").forEach(l => l.trim() && sendEvt({ line: l })));
|
|
6347
6349
|
proc.on("close", code => { sendEvt({ done: true, code }); res.end(); });
|
|
@@ -6375,7 +6377,7 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
|
|
|
6375
6377
|
sendEvt({ line: `Creating tunnel "${name}"…`, step: 1 });
|
|
6376
6378
|
let tunnelId = null;
|
|
6377
6379
|
await new Promise((resolve, reject) => {
|
|
6378
|
-
const proc = spawn("cloudflared", ["tunnel", "create", name], { stdio: ["ignore","pipe","pipe"] });
|
|
6380
|
+
const proc = spawn("cloudflared", ["tunnel", "create", name], { stdio: ["ignore","pipe","pipe"], windowsHide: true });
|
|
6379
6381
|
let output = "";
|
|
6380
6382
|
proc.stdout.on("data", d => { const s = d.toString(); output += s; s.split("\n").forEach(l => l.trim() && sendEvt({ line: l, step: 1 })); });
|
|
6381
6383
|
proc.stderr.on("data", d => { const s = d.toString(); output += s; s.split("\n").forEach(l => l.trim() && sendEvt({ line: l, step: 1 })); });
|
|
@@ -6395,7 +6397,7 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
|
|
|
6395
6397
|
// Step 2: route DNS
|
|
6396
6398
|
sendEvt({ line: `Routing DNS: ${hostname}…`, step: 2 });
|
|
6397
6399
|
await new Promise((resolve) => {
|
|
6398
|
-
const proc = spawn("cloudflared", ["tunnel", "route", "dns", name, hostname], { stdio: ["ignore","pipe","pipe"] });
|
|
6400
|
+
const proc = spawn("cloudflared", ["tunnel", "route", "dns", name, hostname], { stdio: ["ignore","pipe","pipe"], windowsHide: true });
|
|
6399
6401
|
proc.stdout.on("data", d => d.toString().split("\n").forEach(l => l.trim() && sendEvt({ line: l, step: 2 })));
|
|
6400
6402
|
proc.stderr.on("data", d => d.toString().split("\n").forEach(l => l.trim() && sendEvt({ line: l, step: 2 })));
|
|
6401
6403
|
proc.on("close", () => resolve());
|
|
@@ -6877,6 +6879,7 @@ async function actionStart(opts) {
|
|
|
6877
6879
|
detached: true,
|
|
6878
6880
|
stdio: ["ignore", out, out],
|
|
6879
6881
|
env: { ...process.env, __CLAUTH_DAEMON: "1", ...(isStaged ? { __CLAUTH_STAGED: "1" } : {}) },
|
|
6882
|
+
windowsHide: true,
|
|
6880
6883
|
});
|
|
6881
6884
|
child.unref();
|
|
6882
6885
|
|
|
@@ -7101,11 +7104,18 @@ function getAgentPool() {
|
|
|
7101
7104
|
defaultModel: process.env.CLAUTH_AGENT_MODEL || "claude-haiku-4-5",
|
|
7102
7105
|
});
|
|
7103
7106
|
_agentPool.startReaper();
|
|
7107
|
+
console.log(`[agent-pool] init: binary=${_agentPool.binary ? 'found' : 'MISSING'} warmEnabled=${_agentPool.warmEnabled} available=${_agentPool.available()} poolSize=${_agentPool.poolSize} warmSize=${_agentPool.warmSize}`);
|
|
7104
7108
|
// WP-P2: boot persistent re-targetable warm workers in the background so the
|
|
7105
7109
|
// first real call_agent dispatch hits a hot worker (sub-boot latency). Never
|
|
7106
7110
|
// blocks daemon startup; if warm isn't ready yet, dispatch falls back to cold.
|
|
7107
7111
|
if (_agentPool.warmEnabled && _agentPool.available()) {
|
|
7108
|
-
_agentPool.prime().
|
|
7112
|
+
_agentPool.prime().then((r) => {
|
|
7113
|
+
console.log(`[agent-pool] prime complete: mode=${r.mode} warmed=${r.warmed} workers=${r.workers ?? 'n/a'}`);
|
|
7114
|
+
}).catch((e) => {
|
|
7115
|
+
console.error(`[agent-pool] prime failed: ${e.message}`);
|
|
7116
|
+
});
|
|
7117
|
+
} else {
|
|
7118
|
+
console.log(`[agent-pool] prime skipped: warmEnabled=${_agentPool.warmEnabled} available=${_agentPool.available()}`);
|
|
7109
7119
|
}
|
|
7110
7120
|
return _agentPool;
|
|
7111
7121
|
}
|
|
@@ -7907,10 +7917,26 @@ function startTerminalSession(name, knowledge_tier, context_md, cwd) {
|
|
|
7907
7917
|
started_at: new Date().toISOString(),
|
|
7908
7918
|
context: initialContext,
|
|
7909
7919
|
activeProc: null,
|
|
7920
|
+
warmWorker: null,
|
|
7910
7921
|
cwd: cwd || CHITCHAT_FALLBACK_CWD,
|
|
7911
7922
|
};
|
|
7923
|
+
|
|
7924
|
+
// Try to acquire a warm worker from the agent pool for low-latency turns
|
|
7925
|
+
try {
|
|
7926
|
+
const pool = getAgentPool();
|
|
7927
|
+
if (pool) {
|
|
7928
|
+
const worker = pool.acquireForSession(session_id);
|
|
7929
|
+
if (worker) {
|
|
7930
|
+
session.warmWorker = worker;
|
|
7931
|
+
console.log(`[terminal] session ${session_id} acquired warm worker`);
|
|
7932
|
+
}
|
|
7933
|
+
}
|
|
7934
|
+
} catch (e) {
|
|
7935
|
+
console.log(`[terminal] session ${session_id} warm pool unavailable, will use cold path: ${e.message}`);
|
|
7936
|
+
}
|
|
7937
|
+
|
|
7912
7938
|
terminalSessions.set(session_id, session);
|
|
7913
|
-
console.log(`[terminal] started session ${session_id} name=${name} cwd=${session.cwd}`);
|
|
7939
|
+
console.log(`[terminal] started session ${session_id} name=${name} cwd=${session.cwd} warm=${!!session.warmWorker}`);
|
|
7914
7940
|
return { session_id, status: 'ready' };
|
|
7915
7941
|
}
|
|
7916
7942
|
|
|
@@ -7920,6 +7946,49 @@ function sendTerminalMessage(session_id, message) {
|
|
|
7920
7946
|
if (session.status === 'stopped') return { error: 'stopped', message: 'Session is stopped' };
|
|
7921
7947
|
if (session.status === 'busy') return { error: 'session_busy', message: 'Session is busy — try again shortly' };
|
|
7922
7948
|
|
|
7949
|
+
// ── Warm-pool path: dispatch to the pinned worker (maintains its own context) ──
|
|
7950
|
+
if (session.warmWorker && !session.warmWorker.isDead()) {
|
|
7951
|
+
session.status = 'busy';
|
|
7952
|
+
const pool = getAgentPool();
|
|
7953
|
+
pool.dispatchToSession(session_id, { prompt: message })
|
|
7954
|
+
.then((result) => {
|
|
7955
|
+
if (!terminalSessions.has(session_id)) return;
|
|
7956
|
+
const s = terminalSessions.get(session_id);
|
|
7957
|
+
const response = result.ok
|
|
7958
|
+
? (result.package || '').trim() || '(no output)'
|
|
7959
|
+
: `(warm dispatch error: ${result.error || 'unknown'})`;
|
|
7960
|
+
// Still update rolling context for terminal_recv compatibility
|
|
7961
|
+
const turn = `\n\nUser: ${message}\nAssistant: ${response}`;
|
|
7962
|
+
const combined = s.context + turn;
|
|
7963
|
+
s.context = combined.length > 8000 ? combined.slice(combined.length - 8000) : combined;
|
|
7964
|
+
s.lastResponse = response;
|
|
7965
|
+
s.lastResponseAt = new Date().toISOString();
|
|
7966
|
+
s.turn = (s.turn || 0) + 1;
|
|
7967
|
+
s.status = 'ready';
|
|
7968
|
+
s.activeProc = null;
|
|
7969
|
+
console.log(`[terminal] session ${session_id} turn=${s.turn} complete (warm) ok=${result.ok}`);
|
|
7970
|
+
|
|
7971
|
+
// If the warm worker died during dispatch, clear it so next turn falls back to cold
|
|
7972
|
+
if (!result.ok && result.error === 'pinned_worker_died') {
|
|
7973
|
+
s.warmWorker = null;
|
|
7974
|
+
console.log(`[terminal] session ${session_id} warm worker died, next turn will use cold path`);
|
|
7975
|
+
}
|
|
7976
|
+
})
|
|
7977
|
+
.catch((err) => {
|
|
7978
|
+
if (!terminalSessions.has(session_id)) return;
|
|
7979
|
+
const s = terminalSessions.get(session_id);
|
|
7980
|
+
s.lastResponse = `(warm dispatch failed: ${err.message})`;
|
|
7981
|
+
s.lastResponseAt = new Date().toISOString();
|
|
7982
|
+
s.turn = (s.turn || 0) + 1;
|
|
7983
|
+
s.status = 'ready';
|
|
7984
|
+
s.activeProc = null;
|
|
7985
|
+
s.warmWorker = null; // fall back to cold on next turn
|
|
7986
|
+
console.log(`[terminal] session ${session_id} warm dispatch threw, falling back to cold: ${err.message}`);
|
|
7987
|
+
});
|
|
7988
|
+
return { queued: true, session_id, warm: true };
|
|
7989
|
+
}
|
|
7990
|
+
|
|
7991
|
+
// ── Cold-spawn fallback: original path ──
|
|
7923
7992
|
const binary = findClaudeBinary();
|
|
7924
7993
|
if (!binary) return { error: 'binary_not_found', message: 'claude CLI not found in PATH or AppData/npm' };
|
|
7925
7994
|
|
|
@@ -7931,6 +8000,7 @@ function sendTerminalMessage(session_id, message) {
|
|
|
7931
8000
|
env: process.env,
|
|
7932
8001
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
7933
8002
|
shell: true,
|
|
8003
|
+
windowsHide: true,
|
|
7934
8004
|
});
|
|
7935
8005
|
session.activeProc = proc;
|
|
7936
8006
|
|
|
@@ -7955,7 +8025,7 @@ function sendTerminalMessage(session_id, message) {
|
|
|
7955
8025
|
}
|
|
7956
8026
|
});
|
|
7957
8027
|
|
|
7958
|
-
return { queued: true, session_id };
|
|
8028
|
+
return { queued: true, session_id, warm: false };
|
|
7959
8029
|
}
|
|
7960
8030
|
|
|
7961
8031
|
function recvTerminalResponse(session_id, timeout_ms = 30000) {
|
|
@@ -8003,6 +8073,17 @@ function stopTerminalSession(session_id) {
|
|
|
8003
8073
|
if (session.activeProc) {
|
|
8004
8074
|
try { session.activeProc.kill(); } catch {}
|
|
8005
8075
|
}
|
|
8076
|
+
// Release the warm worker back to the pool
|
|
8077
|
+
if (session.warmWorker) {
|
|
8078
|
+
try {
|
|
8079
|
+
const pool = getAgentPool();
|
|
8080
|
+
pool.releaseSession(session_id);
|
|
8081
|
+
console.log(`[terminal] session ${session_id} released warm worker`);
|
|
8082
|
+
} catch (e) {
|
|
8083
|
+
console.log(`[terminal] session ${session_id} warm worker release failed: ${e.message}`);
|
|
8084
|
+
}
|
|
8085
|
+
session.warmWorker = null;
|
|
8086
|
+
}
|
|
8006
8087
|
terminalSessions.delete(session_id);
|
|
8007
8088
|
console.log(`[terminal] stopped session ${session_id}`);
|
|
8008
8089
|
return { stopped: true, session_id };
|
|
@@ -8135,6 +8216,7 @@ function launchVisibleChitchatTerminal(session_id, cwd = CHITCHAT_FALLBACK_CWD)
|
|
|
8135
8216
|
cwd,
|
|
8136
8217
|
detached: true,
|
|
8137
8218
|
stdio: "ignore",
|
|
8219
|
+
windowsHide: true,
|
|
8138
8220
|
});
|
|
8139
8221
|
child.on("error", (err) => {
|
|
8140
8222
|
console.warn(`[ClaudeAItoCLI] visible terminal process error: ${err.message}`);
|
package/package.json
CHANGED
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@lifeaitools/clauth",
|
|
3
|
-
"version": "1.
|
|
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 cli/api.classify.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
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@lifeaitools/clauth",
|
|
3
|
+
"version": "1.18.1",
|
|
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 cli/api.classify.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
|
+
}
|