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()) {