opencode-sandbox 0.1.22 → 0.1.24

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.
package/README.md CHANGED
@@ -125,10 +125,25 @@ Everything else is **blocked by default**.
125
125
 
126
126
  ## Configuration
127
127
 
128
- ### Option 1: Config file
128
+ Config files are stored outside the project directory (in `~/.config/opencode-sandbox/`) so that sandboxed commands cannot modify them. This prevents indirect prompt injection from weakening the sandbox by overwriting the config.
129
+
130
+ ### Config file locations
131
+
132
+ The plugin searches for configuration in this order (first match wins):
133
+
134
+ 1. **Environment variable** `OPENCODE_SANDBOX_CONFIG` (JSON string)
135
+ 2. **Per-project config** `~/.config/opencode-sandbox/projects/<project-name>.json`
136
+ 3. **Global config** `~/.config/opencode-sandbox/config.json`
137
+ 4. **Built-in defaults**
138
+
139
+ The `<project-name>` is the basename of the project directory (e.g., `my-app` for `/home/user/projects/my-app`).
140
+
141
+ If `XDG_CONFIG_HOME` is set, it is used instead of `~/.config`.
142
+
143
+ ### Example: Global config
129
144
 
130
145
  ```json
131
- // .opencode/sandbox.json
146
+ // ~/.config/opencode-sandbox/config.json
132
147
  {
133
148
  "filesystem": {
134
149
  "denyRead": ["~/.ssh", "~/.aws/credentials"],
@@ -149,19 +164,30 @@ Everything else is **blocked by default**.
149
164
  }
150
165
  ```
151
166
 
152
- ### Option 2: Environment variable
167
+ ### Example: Per-project config
168
+
169
+ ```json
170
+ // ~/.config/opencode-sandbox/projects/my-app.json
171
+ {
172
+ "network": {
173
+ "allowedDomains": ["my-internal-api.company.com"]
174
+ }
175
+ }
176
+ ```
177
+
178
+ ### Environment variable
153
179
 
154
180
  ```bash
155
181
  OPENCODE_SANDBOX_CONFIG='{"filesystem":{"denyRead":["~/.ssh"]},"network":{"allowedDomains":["github.com"]}}' opencode
156
182
  ```
157
183
 
158
- ### Option 3: Disable
184
+ ### Disable
159
185
 
160
186
  ```bash
161
187
  OPENCODE_DISABLE_SANDBOX=1 opencode
162
188
  ```
163
189
 
164
- Or in `.opencode/sandbox.json`:
190
+ Or in any config file:
165
191
 
166
192
  ```json
167
193
  {
package/dist/config.d.ts CHANGED
@@ -15,4 +15,5 @@ export interface SandboxPluginConfig {
15
15
  };
16
16
  }
17
17
  export declare function resolveConfig(projectDir: string, worktree: string, user?: SandboxPluginConfig): SandboxRuntimeConfig;
18
+ export declare function getConfigDir(): string;
18
19
  export declare function loadConfig(projectDir: string): Promise<SandboxPluginConfig>;
package/dist/index.js CHANGED
@@ -9,8 +9,13 @@ var DEFAULT_DENY_READ_DIRS = [
9
9
  ".ssh",
10
10
  ".gnupg",
11
11
  ".aws/credentials",
12
+ ".azure",
12
13
  ".config/gcloud",
14
+ ".config/gh",
15
+ ".kube",
16
+ ".docker/config.json",
13
17
  ".npmrc",
18
+ ".netrc",
14
19
  ".env"
15
20
  ];
16
21
  var DEFAULT_ALLOWED_DOMAINS = [
@@ -68,6 +73,18 @@ function resolveConfig(projectDir, worktree, user) {
68
73
  }
69
74
  };
70
75
  }
76
+ function getConfigDir() {
77
+ const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), ".config");
78
+ return path.join(xdgConfig, "opencode-sandbox");
79
+ }
80
+ async function tryLoadJsonFile(filePath) {
81
+ try {
82
+ const content = await fs.readFile(filePath, "utf-8");
83
+ return JSON.parse(content);
84
+ } catch {
85
+ return null;
86
+ }
87
+ }
71
88
  async function loadConfig(projectDir) {
72
89
  const envConfig = process.env.OPENCODE_SANDBOX_CONFIG;
73
90
  if (envConfig) {
@@ -77,13 +94,15 @@ async function loadConfig(projectDir) {
77
94
  console.warn("[opencode-sandbox] Invalid JSON in OPENCODE_SANDBOX_CONFIG, using defaults");
78
95
  }
79
96
  }
80
- const configPath = path.join(projectDir, ".opencode", "sandbox.json");
81
- try {
82
- const content = await fs.readFile(configPath, "utf-8");
83
- return JSON.parse(content);
84
- } catch {
85
- return {};
86
- }
97
+ const configDir = getConfigDir();
98
+ const projectName = path.basename(projectDir);
99
+ const projectConfig = await tryLoadJsonFile(path.join(configDir, "projects", `${projectName}.json`));
100
+ if (projectConfig)
101
+ return projectConfig;
102
+ const globalConfig = await tryLoadJsonFile(path.join(configDir, "config.json"));
103
+ if (globalConfig)
104
+ return globalConfig;
105
+ return {};
87
106
  }
88
107
 
89
108
  // src/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-sandbox",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "OpenCode plugin that sandboxes agent commands using @anthropic-ai/sandbox-runtime (seatbelt on macOS, bubblewrap on Linux)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",