@crouton-kit/humanloop 0.3.1 → 0.3.2

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.
@@ -44,6 +44,22 @@ function binaryOk() {
44
44
  return false;
45
45
  }
46
46
  }
47
+ // Returns the termrender version installed in the managed venv (via
48
+ // importlib.metadata), or null if the venv is missing/broken or termrender is
49
+ // not installed. Used by ensureRenderer() to detect drift from the pin and
50
+ // trigger a reinstall — otherwise a venv provisioned at an older pin sticks
51
+ // forever (binaryOk passes for any working binary, regardless of version).
52
+ function installedVersion() {
53
+ if (!existsSync(VENV_PYTHON))
54
+ return null;
55
+ try {
56
+ const out = execFileSync(VENV_PYTHON, ['-c', 'import importlib.metadata as m; print(m.version("termrender"))'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 5000 });
57
+ return out.trim() || null;
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ }
47
63
  function uvAvailable() {
48
64
  try {
49
65
  execFileSync('uv', ['--version'], { stdio: 'pipe', timeout: 5000 });
@@ -70,7 +86,7 @@ export function ensureRenderer() {
70
86
  rendererState = 'unavailable';
71
87
  return;
72
88
  }
73
- if (binaryOk()) {
89
+ if (binaryOk() && installedVersion() === TERMRENDER_VERSION) {
74
90
  rendererState = 'ready';
75
91
  return;
76
92
  }
@@ -81,7 +97,12 @@ export function ensureRenderer() {
81
97
  return;
82
98
  }
83
99
  try {
84
- execFileSync('uv', ['venv', VENV_DIR], { stdio: 'pipe', timeout: 60000 });
100
+ // Skip venv creation on drift (venv exists with wrong termrender version)
101
+ // — `uv pip install` into the existing venv replaces it in place. Only
102
+ // create when the venv directory is genuinely absent.
103
+ if (!existsSync(VENV_DIR)) {
104
+ execFileSync('uv', ['venv', VENV_DIR], { stdio: 'pipe', timeout: 60000 });
105
+ }
85
106
  execFileSync('uv', ['pip', 'install', '--python', VENV_PYTHON, `termrender==${TERMRENDER_VERSION}`], { stdio: 'pipe', timeout: 120000 });
86
107
  }
87
108
  catch (err) {
@@ -89,7 +110,7 @@ export function ensureRenderer() {
89
110
  rendererState = 'unavailable';
90
111
  return;
91
112
  }
92
- rendererState = binaryOk() ? 'ready' : 'unavailable';
113
+ rendererState = (binaryOk() && installedVersion() === TERMRENDER_VERSION) ? 'ready' : 'unavailable';
93
114
  if (rendererState === 'unavailable') {
94
115
  process.stderr.write('[hl] termrender install completed but health check failed; using plaintext fallback\n');
95
116
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crouton-kit/humanloop",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Human-in-the-loop decision TUI — agents write questions, humans answer them",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",