vision-electronic-indexing-pi 0.1.7 → 0.1.8

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.
@@ -18,6 +18,8 @@ Then in Pi:
18
18
 
19
19
  Setup creates/checks a Pi-managed Python virtual environment at `~/.pi/agent/vision-inventory/.venv`, installs Python dependencies there when approved, warns that datasheet lookup needs a separate web-search/browser capability, and prompts for Cloudflare Workers AI API token credentials when needed.
20
20
 
21
+ On Debian/Ubuntu, Python venv creation may require `python3-venv` or a version-specific package such as `python3.10-venv`. If setup reports that `ensurepip` is unavailable, install the package, remove the incomplete venv with `rm -rf ~/.pi/agent/vision-inventory/.venv`, and rerun `/vision-inventory-setup`.
22
+
21
23
  Credentials are stored at:
22
24
 
23
25
  ```text
@@ -3,7 +3,7 @@ import { StringEnum } from "@earendil-works/pi-ai";
3
3
  import { Type } from "typebox";
4
4
  import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
5
5
  import { existsSync } from "node:fs";
6
- import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
6
+ import { chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises";
7
7
  import { homedir } from "node:os";
8
8
  import { dirname, isAbsolute, join, resolve } from "node:path";
9
9
  import { fileURLToPath } from "node:url";
@@ -15,6 +15,7 @@ const EXTENSION_DIR = dirname(fileURLToPath(import.meta.url));
15
15
  const CONFIG_DIR = join(homedir(), ".pi", "agent", "vision-inventory");
16
16
  const VENV_DIR = join(CONFIG_DIR, ".venv");
17
17
  const VENV_PYTHON = process.platform === "win32" ? join(VENV_DIR, "Scripts", "python.exe") : join(VENV_DIR, "bin", "python");
18
+ const VENV_PIP = process.platform === "win32" ? join(VENV_DIR, "Scripts", "pip.exe") : join(VENV_DIR, "bin", "pip");
18
19
  const CREDENTIALS_FILE = join(CONFIG_DIR, "credentials.json");
19
20
 
20
21
  type VisionCredentials = {
@@ -218,14 +219,45 @@ async function buildPythonEnv(): Promise<NodeJS.ProcessEnv> {
218
219
  };
219
220
  }
220
221
 
222
+ function hasCompleteVenv(): boolean {
223
+ return existsSync(VENV_PYTHON) && existsSync(VENV_PIP);
224
+ }
225
+
221
226
  async function getPythonCommand(): Promise<string> {
222
- return existsSync(VENV_PYTHON) ? VENV_PYTHON : BASE_PYTHON_COMMAND;
227
+ return hasCompleteVenv() ? VENV_PYTHON : BASE_PYTHON_COMMAND;
228
+ }
229
+
230
+ function venvHelpText(): string {
231
+ return [
232
+ `Vision Inventory Python venv path: ${VENV_DIR}`,
233
+ "On Debian/Ubuntu, venv creation with pip requires python3-venv.",
234
+ "Install it with: sudo apt install python3-venv",
235
+ "If your system asks for a version-specific package, install that instead, e.g. sudo apt install python3.10-venv",
236
+ ].join("\n");
223
237
  }
224
238
 
225
239
  async function ensurePythonEnvironment(pi: ExtensionAPI, packageRoot: string, ctx: { ui: any; hasUI: boolean }): Promise<boolean> {
226
- if (!existsSync(VENV_PYTHON)) {
240
+ if (existsSync(VENV_PYTHON) && !existsSync(VENV_PIP)) {
241
+ const message = `Existing Vision Inventory venv is incomplete because pip is missing.\n${venvHelpText()}`;
242
+ if (!ctx.hasUI) {
243
+ ctx.ui.notify(message, "error");
244
+ return false;
245
+ }
246
+
247
+ const recreate = await ctx.ui.confirm(
248
+ "Recreate incomplete Vision Inventory Python virtual environment?",
249
+ `${message}\n\nChoose No if you have not installed python3-venv yet. After installing it, rerun /vision-inventory-setup.`
250
+ );
251
+ if (!recreate) {
252
+ ctx.ui.notify(message, "error");
253
+ return false;
254
+ }
255
+ await rm(VENV_DIR, { recursive: true, force: true });
256
+ }
257
+
258
+ if (!hasCompleteVenv()) {
227
259
  if (!ctx.hasUI) {
228
- ctx.ui.notify(`Vision Inventory Python venv is missing. Run /vision-inventory-setup interactively, or install dependencies manually with ${BASE_PYTHON_COMMAND} -m pip install -r ${join(packageRoot, "requirements.txt")}`, "error");
260
+ ctx.ui.notify(`Vision Inventory Python venv is missing or incomplete. Run /vision-inventory-setup interactively, or install dependencies manually with ${BASE_PYTHON_COMMAND} -m pip install -r ${join(packageRoot, "requirements.txt")}\n${venvHelpText()}`, "error");
229
261
  return false;
230
262
  }
231
263
 
@@ -237,7 +269,11 @@ async function ensurePythonEnvironment(pi: ExtensionAPI, packageRoot: string, ct
237
269
 
238
270
  await mkdir(CONFIG_DIR, { recursive: true });
239
271
  const venvResult = await pi.exec(BASE_PYTHON_COMMAND, ["-m", "venv", VENV_DIR], { timeout: 120_000 });
240
- if (venvResult.code !== 0) throw new Error(venvResult.stderr || venvResult.stdout || "Python venv creation failed");
272
+ if (venvResult.code !== 0 || !hasCompleteVenv()) {
273
+ await rm(VENV_DIR, { recursive: true, force: true });
274
+ ctx.ui.notify(`${venvResult.stderr || venvResult.stdout || "Python venv creation failed"}\n${venvHelpText()}`, "error");
275
+ return false;
276
+ }
241
277
  }
242
278
 
243
279
  const deps = await pi.exec(VENV_PYTHON, ["-c", "import mcp, requests, PIL, dotenv; print('ok')"], { timeout: 10_000 });
@@ -252,7 +288,10 @@ async function ensurePythonEnvironment(pi: ExtensionAPI, packageRoot: string, ct
252
288
  if (!install) return false;
253
289
 
254
290
  const result = await pi.exec(VENV_PYTHON, ["-m", "pip", "install", "-r", join(packageRoot, "requirements.txt")], { timeout: 120_000 });
255
- if (result.code !== 0) throw new Error(result.stderr || result.stdout || "pip install failed");
291
+ if (result.code !== 0) {
292
+ ctx.ui.notify(result.stderr || result.stdout || "pip install failed", "error");
293
+ return false;
294
+ }
256
295
  return true;
257
296
  }
258
297
 
package/README.md CHANGED
@@ -48,6 +48,8 @@ Start Pi and run:
48
48
 
49
49
  The setup command creates/checks a Pi-managed Python virtual environment under `~/.pi/agent/vision-inventory/.venv`, installs Python dependencies there when approved, warns that datasheet enrichment needs a separate web-search/browser capability, and prompts for Cloudflare Workers AI API token credentials the first time.
50
50
 
51
+ On Debian/Ubuntu, Python venv creation may require the system package `python3-venv` or a version-specific package such as `python3.10-venv`. If setup reports that `ensurepip` is unavailable, install the package, remove the incomplete venv with `rm -rf ~/.pi/agent/vision-inventory/.venv`, and rerun `/vision-inventory-setup`.
52
+
51
53
  Credentials are stored at:
52
54
 
53
55
  ```text
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vision-electronic-indexing-pi",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Pi package for agent-assisted electronics/PCB image inventory with Cloudflare Workers AI vision and datasheet enrichment.",
5
5
  "license": "MIT",
6
6
  "repository": {