@sigit / sigit-vscode / commits / 816b8de

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
@@ -1,8 +1,11 @@
1 .vscode/**
2 .github/**
3 +.claude/**
4 src/**
5 test/**
6 node_modules/**
7 +pnpm-lock.yaml
8 +pnpm-workspace.yaml
9 **/*.ts
10 **/*.map
11 esbuild.js
CHANGELOG.md
+18
@@ -5,6 +5,24 @@ All notable changes to the **siGit Code** extension are documented here.
5 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
8 +## [1.0.2] - 2026-06-26
9 +
10 +### Fixed
11 +
12 +- Model load failed with `Operation not permitted (os error 1)` (EPERM) when the
13 + agent ran outside the Onde Inference app. The `sigit` agent redirects its
14 + HuggingFace cache into a macOS App Group container that only entitled,
15 + app-sandboxed processes may write to; a `sigit` spawned by VS Code has no such
16 + entitlement. The extension now passes writable `HF_HOME` / `HF_HUB_CACHE`
17 + defaults (`~/.cache/huggingface`) so model downloads land in a directory the
18 + editor's child process can write to. A real `HF_HOME`/`HF_HUB_CACHE` env var or
19 + an agent `env` entry still takes precedence.
20 +
21 +### Changed
22 +
23 +- Packaging now excludes `.claude/` and lockfiles from the VSIX, shrinking the
24 + bundle and preventing stray worktree copies from being shipped.
25 +
26 ## [1.0.1] - 2026-06-25
27
28 ### Fixed
package.json
+1 -1
@@ -2,7 +2,7 @@
2 "name": "sigit-code",
3 "displayName": "siGit Code — On-device AI Coding Agent",
4 "description": "Local-first AI coding agent for VS Code. Runs the on-device sigit agent, and other ACP-compatible agents, over stdio.",
5 - "version": "1.0.1",
5 + "version": "1.0.2",
6 "publisher": "getsigit",
7 "license": "MIT",
8 "packageManager": "pnpm@10.33.0",
src/acp/client.ts
+11 -2
@@ -2,7 +2,7 @@ import { ChildProcessWithoutNullStreams, spawn } from "child_process";
2 import { EventEmitter } from "events";
3 import { delimiter } from "path";
4 import { Connection } from "./connection";
5 -import { augmentedPath, resolveExecutable } from "./resolveCommand";
5 +import { augmentedPath, defaultModelCacheEnv, resolveExecutable } from "./resolveCommand";
6
7 /** Thrown when the agent executable cannot be located on the (augmented) PATH. */
8 export class AgentNotFoundError extends Error {
@@ -79,8 +79,17 @@ export class AcpClient extends EventEmitter {
79 spawn(config: AgentSpawnConfig): void {
80 // GUI-launched VS Code inherits a minimal PATH; augment it so the agent
81 // (and any subprocess it spawns) can be found and can find its own tools.
82 + // Model-cache defaults sit *under* the inherited env and the agent config so
83 + // a real HF_HOME/HF_HUB_CACHE (or an agent `env` entry) always wins; they
84 + // only fill in a writable cache dir when nothing else is set, avoiding the
85 + // EPERM that the App Group container would otherwise cause.
86 const path = augmentedPath();
83 - const env = { ...process.env, ...(config.env ?? {}), PATH: path };
87 + const env = {
88 + ...defaultModelCacheEnv(),
89 + ...process.env,
90 + ...(config.env ?? {}),
91 + PATH: path
92 + };
93 if (config.env?.PATH) {
94 env.PATH = `${config.env.PATH}${delimiter}${path}`;
95 }
src/acp/resolveCommand.ts
+21
@@ -99,6 +99,27 @@ export function augmentedPath(): string {
99 return parts.join(delimiter);
100 }
101
102 +/**
103 + * Sandbox-safe HuggingFace cache defaults.
104 + *
105 + * The on-device `sigit` agent redirects its model cache into a macOS App Group
106 + * container (`~/Library/Group Containers/group.com.ondeinference.apps/…`) so it
107 + * can share weights with the Onde Inference desktop app. That container is only
108 + * writable by processes carrying the matching App Group entitlement; a `sigit`
109 + * spawned by VS Code has none, so model downloads fail with EPERM ("Operation
110 + * not permitted", os error 1). Pointing HF_HOME / HF_HUB_CACHE at the standard
111 + * per-user cache keeps downloads in a directory the editor's child process can
112 + * actually write to. These are *defaults* — a real env var or an agent's `env`
113 + * entry still wins (see AcpClient.spawn).
114 + */
115 +export function defaultModelCacheEnv(): Record<string, string> {
116 + const hfHome = join(homedir(), ".cache", "huggingface");
117 + return {
118 + HF_HOME: hfHome,
119 + HF_HUB_CACHE: join(hfHome, "hub")
120 + };
121 +}
122 +
123 function isExecutableFile(p: string): boolean {
124 try {
125 if (!statSync(p).isFile()) {