Fix model-load EPERM by overriding sigit's App Group HF cache

sigit redirects HF_HOME/HF_HUB_CACHE into the macOS App Group container group.com.ondeinference.apps, which only entitled app-sandboxed processes may write to. Spawned by VS Code (no entitlement), model downloads failed with `Operation not permitted (os error 1)`. Pass writable HF_HOME/HF_HUB_CACHE defaults (~/.cache/huggingface) under the inherited env and agent config, so a real env var or agent `env` entry still wins. Also exclude .claude/ and lockfiles from the VSIX. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

paydii committed Jun 26, 2026 at 00:27 UTC 816b8de6e4a147a98048a2969e5c497cd5c7387c
5 files changed +54 -3
.vscodeignore
+3
index 47e100c..39da8f8 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -1,8 +1,11 @@ .vscode/** .github/** +.claude/** src/** test/** node_modules/** +pnpm-lock.yaml +pnpm-workspace.yaml **/*.ts **/*.map esbuild.js
CHANGELOG.md
+18
index 379b1fe..aa12b56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,24 @@ All notable changes to the **siGit Code** extension are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.0.2] - 2026-06-26 + +### Fixed + +- Model load failed with `Operation not permitted (os error 1)` (EPERM) when the + agent ran outside the Onde Inference app. The `sigit` agent redirects its + HuggingFace cache into a macOS App Group container that only entitled, + app-sandboxed processes may write to; a `sigit` spawned by VS Code has no such + entitlement. The extension now passes writable `HF_HOME` / `HF_HUB_CACHE` + defaults (`~/.cache/huggingface`) so model downloads land in a directory the + editor's child process can write to. A real `HF_HOME`/`HF_HUB_CACHE` env var or + an agent `env` entry still takes precedence. + +### Changed + +- Packaging now excludes `.claude/` and lockfiles from the VSIX, shrinking the + bundle and preventing stray worktree copies from being shipped. + ## [1.0.1] - 2026-06-25 ### Fixed
package.json
+1 -1
index 50a46de..06c0b77 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "sigit-code", "displayName": "siGit Code — On-device AI Coding Agent", "description": "Local-first AI coding agent for VS Code. Runs the on-device sigit agent, and other ACP-compatible agents, over stdio.", - "version": "1.0.1", + "version": "1.0.2", "publisher": "getsigit", "license": "MIT", "packageManager": "pnpm@10.33.0",
src/acp/client.ts
+11 -2
index 2201e5b..886fb55 100644 --- a/src/acp/client.ts +++ b/src/acp/client.ts @@ -2,7 +2,7 @@ import { ChildProcessWithoutNullStreams, spawn } from "child_process"; import { EventEmitter } from "events"; import { delimiter } from "path"; import { Connection } from "./connection"; -import { augmentedPath, resolveExecutable } from "./resolveCommand"; +import { augmentedPath, defaultModelCacheEnv, resolveExecutable } from "./resolveCommand"; /** Thrown when the agent executable cannot be located on the (augmented) PATH. */ export class AgentNotFoundError extends Error { @@ -79,8 +79,17 @@ export class AcpClient extends EventEmitter { spawn(config: AgentSpawnConfig): void { // GUI-launched VS Code inherits a minimal PATH; augment it so the agent // (and any subprocess it spawns) can be found and can find its own tools. + // Model-cache defaults sit *under* the inherited env and the agent config so + // a real HF_HOME/HF_HUB_CACHE (or an agent `env` entry) always wins; they + // only fill in a writable cache dir when nothing else is set, avoiding the + // EPERM that the App Group container would otherwise cause. const path = augmentedPath(); - const env = { ...process.env, ...(config.env ?? {}), PATH: path }; + const env = { + ...defaultModelCacheEnv(), + ...process.env, + ...(config.env ?? {}), + PATH: path + }; if (config.env?.PATH) { env.PATH = `${config.env.PATH}${delimiter}${path}`; }
src/acp/resolveCommand.ts
+21
index f86c49f..79d0c1a 100644 --- a/src/acp/resolveCommand.ts +++ b/src/acp/resolveCommand.ts @@ -99,6 +99,27 @@ export function augmentedPath(): string { return parts.join(delimiter); } +/** + * Sandbox-safe HuggingFace cache defaults. + * + * The on-device `sigit` agent redirects its model cache into a macOS App Group + * container (`~/Library/Group Containers/group.com.ondeinference.apps/…`) so it + * can share weights with the Onde Inference desktop app. That container is only + * writable by processes carrying the matching App Group entitlement; a `sigit` + * spawned by VS Code has none, so model downloads fail with EPERM ("Operation + * not permitted", os error 1). Pointing HF_HOME / HF_HUB_CACHE at the standard + * per-user cache keeps downloads in a directory the editor's child process can + * actually write to. These are *defaults* — a real env var or an agent's `env` + * entry still wins (see AcpClient.spawn). + */ +export function defaultModelCacheEnv(): Record<string, string> { + const hfHome = join(homedir(), ".cache", "huggingface"); + return { + HF_HOME: hfHome, + HF_HUB_CACHE: join(hfHome, "hub") + }; +} + function isExecutableFile(p: string): boolean { try { if (!statSync(p).isFile()) {