@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.
Files changed (2) hide show
  1. package/cli/commands/serve.js +88 -6
  2. package/package.json +65 -65
@@ -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().catch(() => {});
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.17.0",
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
+ }