You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jul 17, 2026. It is now read-only.
Repository navigation
Commit 4997660
Browse filesBrowse the repository at this point in the historyBrowse files
feat: multi-location .env loading with last-wins merge strategy
Read .env from two locations and merge with cascading priority:
1. ~/.config/opencode/.env (global defaults)
2. <projectDir>/.opencode/.env (project overrides, wins)
BREAKING: .env values now override OS environment variables,
matching the opencode-cli convention (local overrides user).
Copy file name to clipboardExpand all lines: README.md
+17-6Lines changed: 17 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,20 +1,31 @@
1
1
# opencode-plugin-shell-env
2
2
3
-
Loads `.opencode/.env` variables into OpenCode's shell environment and MCP server processes.
3
+
Loads `.env` variables into OpenCode's shell environment, MCP server processes, and `process.env` for downstream plugins.
4
4
5
5
## Problem
6
6
7
-
OpenCode's `opencode.json` supports environment variable references like `{env:N8N_MCP_BEARER_TOKEN}`, but these only resolve **OS-level environment variables** (i.e., variables exported in the shell). An `.opencode/.env` file is **not** read by default.
7
+
OpenCode's `opencode.json` supports environment variable references like `{env:N8N_MCP_BEARER_TOKEN}`, but these only resolve **OS-level environment variables** (i.e., variables exported in the shell). An `.env` file is **not** read by default.
8
8
9
9
## Solution
10
10
11
-
This plugin hooks into OpenCode's `shell.env` lifecycle event and injects variables from `<projectRoot>/.opencode/.env` into every shell command and MCP server process spawned by OpenCode.
11
+
This plugin hooks into OpenCode's `shell.env` lifecycle event and injects variables from `.env` files into every shell command, MCP server process, and `process.env` for downstream plugins.
12
+
13
+
### .env Loading Order (Last Wins)
14
+
15
+
The plugin reads `.env` files from two locations and merges them — more specific sources override less specific ones:
16
+
17
+
| Priority | Source | Purpose |
18
+
|----------|--------|---------|
19
+
| 1 (base) |`~/.config/opencode/.env`| Global defaults (user email, shared API keys) |
Both layers **override** existing OS environment variables. If a key appears in both files, the project-level value wins. This matches the "last wins" convention used by the opencode-cli plugin discovery (local overrides user).
30
+
22
31
This eliminates the need for each plugin to implement its own `.env` file parsing.
23
32
24
33
## When to Use This Skill
@@ -33,36 +42,50 @@ This eliminates the need for each plugin to implement its own `.env` file parsin
When OpenCode loads the `shell-env` plugin, it reads `.opencode/.env` and injects all variables into `process.env`**before** subsequent plugins are initialized.
45
+
When OpenCode loads the `shell-env` plugin, it reads `.env` files from both locations, merges them (last wins), and injects all variables into `process.env`**before** subsequent plugins are initialized.
37
46
38
47
```
39
48
Plugin loading order (.opencode/package.json dependencies):
40
-
1. shell-env ← reads .env, sets process.env
49
+
1. shell-env ← reads global + project .env, sets process.env
41
50
2. time-tracking ← can read process.env.OPENCODE_USER_EMAIL
42
51
3. other-plugin ← can read process.env.MY_SECRET
43
52
```
44
53
45
54
**Rules:**
46
-
- Existing `process.env` values are **never overwritten** (OS-level exports take precedence)
47
-
- If `.opencode/.env` is missing or unreadable, the plugin silently continues
55
+
-`.env` values **override** existing OS environment variables (last wins)
56
+
- Project `.env` overrides global `.env` for the same key
57
+
- If either `.env` file is missing or unreadable, the plugin silently continues
48
58
- Variables are available immediately after plugin init — no async delay
49
59
50
60
### Phase 2: Shell Execution (`shell.env` hook)
51
61
52
-
On every shell command or MCP server process, the plugin re-reads `.opencode/.env` and injects variables into the shell environment.
62
+
On every shell command or MCP server process, the plugin re-reads both `.env`files and injects merged variables into the shell environment.
53
63
54
64
```
55
65
Shell command execution:
56
66
1. OpenCode calls "shell.env" hook
57
-
2. shell-env injects .env variables into output.env
58
-
3. Shell command runs with merged environment
67
+
2. shell-env reads global + project .env, merges (last wins)
68
+
3. Merged variables injected into output.env
69
+
4. Shell command runs with merged environment
59
70
```
60
71
61
72
**Rules:**
62
73
- Re-reads `.env` on every invocation (picks up changes without restart)
63
-
-Existing shell environment variables are **never overwritten**
0 commit comments