@hybridlabor-api/bdb-hardware-pcb 0.1.1 → 0.1.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.
Files changed (2) hide show
  1. package/installer.js +38 -0
  2. package/package.json +1 -1
package/installer.js CHANGED
@@ -25,6 +25,7 @@
25
25
  const os = require('os');
26
26
  const path = require('path');
27
27
  const fs = require('fs');
28
+ const crypto = require('crypto');
28
29
  const { spawnSync } = require('child_process');
29
30
 
30
31
  const AUTO = process.argv.includes('--auto');
@@ -94,12 +95,48 @@ function findKicadCliPath() {
94
95
  return 'kicad-cli';
95
96
  }
96
97
 
98
+ // Hash of pyproject.toml, used as a cheap "did the dependency spec change"
99
+ // marker. AOS's swap-in-place upgrade preserves .venv across a version bump
100
+ // (that's the whole point of the PRESERVE list), so "the venv dir exists" is
101
+ // NOT enough on its own to prove it's still current for THIS version -- the
102
+ // hash comparison is what makes skipping safe across an upgrade that did
103
+ // change deps, not just across an unattended re-run that didn't.
104
+ function depsSpecHash(serverDir) {
105
+ const p = path.join(serverDir, 'pyproject.toml');
106
+ if (!fs.existsSync(p)) return null;
107
+ return crypto.createHash('sha256').update(fs.readFileSync(p)).digest('hex');
108
+ }
109
+
97
110
  function setupServerEnv(server, uvBin, pythonBin) {
98
111
  const venvDir = path.join(server.dir, '.venv');
112
+ const markerPath = path.join(venvDir, '.aos-deps-hash');
113
+ const currentHash = depsSpecHash(server.dir);
114
+
115
+ // Every Quick Update used to re-run `uv sync` / `pip install` here
116
+ // unconditionally, even when downloadOrUpdateModule() (in the main AOS
117
+ // installer) had already determined this module's version hadn't
118
+ // changed at all -- real network calls and, on the pip fallback path
119
+ // with no uv on PATH, a genuinely slow full dependency resolve, every
120
+ // single run, for nothing.
121
+ if (currentHash && fs.existsSync(venvDir) && fs.existsSync(markerPath)) {
122
+ try {
123
+ if (fs.readFileSync(markerPath, 'utf8').trim() === currentHash) {
124
+ log.ok(`${server.name}-mcp-server: dependencies already up to date, skipping sync`);
125
+ return true;
126
+ }
127
+ } catch (e) { /* fall through to a real sync if the marker is unreadable */ }
128
+ }
129
+
130
+ const markDone = () => {
131
+ if (!currentHash) return;
132
+ try { fs.writeFileSync(markerPath, currentHash); } catch (e) { /* non-fatal: just means next run re-syncs once more */ }
133
+ };
134
+
99
135
  if (uvBin) {
100
136
  const res = spawnSync(uvBin, ['sync'], { cwd: server.dir, stdio: 'inherit' });
101
137
  if (res.status === 0) {
102
138
  log.ok(`${server.name}-mcp-server: dependencies synced via uv`);
139
+ markDone();
103
140
  return true;
104
141
  }
105
142
  log.warn(`${server.name}-mcp-server: 'uv sync' failed (exit ${res.status}); falling back to venv+pip`);
@@ -122,6 +159,7 @@ function setupServerEnv(server, uvBin, pythonBin) {
122
159
  return false;
123
160
  }
124
161
  log.ok(`${server.name}-mcp-server: dependencies installed via venv+pip`);
162
+ markDone();
125
163
  return true;
126
164
  }
127
165
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hybridlabor-api/bdb-hardware-pcb",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "BDB Hardware & PCB — KiCad + OpenSCAD MCP servers and AI-era skills for schematic capture, PCB layout/routing, DFM sign-off, and parametric 3D enclosure design",
5
5
  "main": "installer.js",
6
6
  "bin": {