opencode2-direnv 2026.908.0 → 2026.908.2
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 +37 -3
- package/dist/index.d.ts +90 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +219 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +265 -30
package/README.md
CHANGED
|
@@ -72,7 +72,39 @@ direnv: .envrc is blocked. Run `direnv allow` to enable.
|
|
|
72
72
|
|
|
73
73
|
### Local development
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
To dogfood this repository's working tree instead of the published package
|
|
76
|
+
(this repo's own setup), disable the published plugin and load a local dev
|
|
77
|
+
instance with a **distinct plugin id**:
|
|
78
|
+
|
|
79
|
+
```jsonc
|
|
80
|
+
// opencode.json (project)
|
|
81
|
+
{
|
|
82
|
+
"plugins": ["-opencode2-direnv"]
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
// .opencode/plugins/dev/index.ts — auto-discovered, not published
|
|
88
|
+
const plugin = (await import(`../../../src/index.js?dev=${Date.now()}`)).default
|
|
89
|
+
|
|
90
|
+
export default { ...plugin, id: "opencode2-direnv-dev" }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Three details matter:
|
|
94
|
+
|
|
95
|
+
- **Distinct id** — without it the local instance's own `opencode2-direnv` id
|
|
96
|
+
re-enables the disabled package ("a later id re-enables a disabled plugin")
|
|
97
|
+
and then fails with `Duplicate plugin ID`.
|
|
98
|
+
- **Cache-busted dynamic import** — OpenCode cache-busts only the entrypoint
|
|
99
|
+
file (`index.ts?mtime=…`); a static import of `src/index.js` is served from
|
|
100
|
+
the module cache for the server's lifetime, so `src/` edits would silently
|
|
101
|
+
run stale code until a service restart. The per-evaluation query makes every
|
|
102
|
+
wrapper reload import the current working tree.
|
|
103
|
+
- **`.opencode/plugins/`** — configured path entries must be *directories* on
|
|
104
|
+
current betas; direct files load only from `.opencode/plugins/`.
|
|
105
|
+
|
|
106
|
+
In other projects (without a globally installed copy), a plain directory entry
|
|
107
|
+
also works and needs no disable or distinct id:
|
|
76
108
|
|
|
77
109
|
```json
|
|
78
110
|
{
|
|
@@ -80,11 +112,13 @@ Local plugins load from a directory containing an `index.ts` entrypoint:
|
|
|
80
112
|
}
|
|
81
113
|
```
|
|
82
114
|
|
|
83
|
-
The root `index.ts` re-exports `src/index.ts
|
|
115
|
+
The root `index.ts` re-exports `src/index.ts`; with the plain entry, edits are
|
|
116
|
+
picked up on restart. Typecheck, test, and build with:
|
|
84
117
|
|
|
85
118
|
```bash
|
|
86
119
|
npm ci
|
|
87
120
|
npx tsc --noEmit
|
|
121
|
+
npm test
|
|
88
122
|
npm run build
|
|
89
123
|
```
|
|
90
124
|
|
|
@@ -100,7 +134,7 @@ plugin setup ────▶ direnv export json ──▶ process.env reconcile
|
|
|
100
134
|
|
|
101
135
|
1. **Discovery** — Searches upward from the plugin's location directory, stopping at the git root
|
|
102
136
|
2. **Export** — Runs `direnv export json` (fast when nothing changed; direnv's own watch caches it)
|
|
103
|
-
3. **Reconcile** — Applies additions/changes and *removes* dropped keys; explicit direnv unsets (`null` values) are honored
|
|
137
|
+
3. **Reconcile** — Applies additions/changes and *removes* dropped keys; explicit direnv unsets (`null` values) are honored. Keys are reference-counted across parallel projects, so one project's reload can't delete another's live vars; fully released keys revert to their pre-plugin values
|
|
104
138
|
4. **Inject** — The `shell.create.before` hook copies the cached export into the environment of every shell spawned below the devshell directory
|
|
105
139
|
|
|
106
140
|
## Troubleshooting
|
package/dist/index.d.ts
CHANGED
|
@@ -6,10 +6,32 @@ export declare const sanePath: () => string;
|
|
|
6
6
|
export declare const direnvCandidates: () => string[];
|
|
7
7
|
/** Strip known poison from process.env; returns the removed keys. */
|
|
8
8
|
export declare const stripPoison: () => string[];
|
|
9
|
+
/**
|
|
10
|
+
* The environment `direnv export json` is invoked with.
|
|
11
|
+
*
|
|
12
|
+
* direnv computes its export as a *diff against the invoking environment*, so
|
|
13
|
+
* the invoking environment must be STABLE and independent of what this plugin
|
|
14
|
+
* previously applied:
|
|
15
|
+
*
|
|
16
|
+
* - Invoking direnv with vars we applied on an earlier reload makes direnv
|
|
17
|
+
* omit them from the export; the plugin would read that as "dropped",
|
|
18
|
+
* delete them, and the next export would re-add them — oscillating (`+N` /
|
|
19
|
+
* `-N`) on every no-op reload.
|
|
20
|
+
* - Conversely, stripping applied vars from the real environment is wrong
|
|
21
|
+
* too: removing `PATH` makes the devshell evaluate against an empty PATH,
|
|
22
|
+
* exporting a PATH with no system/profile entries at all.
|
|
23
|
+
*
|
|
24
|
+
* So direnv always runs against this fixed, minimal baseline — the export
|
|
25
|
+
* becomes a pure function of the devshell itself, like a fresh login shell
|
|
26
|
+
* entering the project directory.
|
|
27
|
+
*/
|
|
9
28
|
/**
|
|
10
29
|
* Filter a `direnv export json` payload down to variables that are safe to
|
|
11
|
-
* apply: valid POSIX names only (drops phantom entries like `export PATH`)
|
|
12
|
-
*
|
|
30
|
+
* apply: valid POSIX names only (drops phantom entries like `export PATH`),
|
|
31
|
+
* no script-valued vars (drops nix's `shellHook` and friends), and no direnv
|
|
32
|
+
* bookkeeping vars (`DIRENV_DIFF`, `DIRENV_WATCHES`, … churn on every
|
|
33
|
+
* evaluation and exist for the wrapping shell's eval, not for consumers —
|
|
34
|
+
* applying them makes reloads oscillate and pollutes spawned shells).
|
|
13
35
|
*/
|
|
14
36
|
export declare const filterVars: (vars: Record<string, string | null | undefined>) => Record<string, string>;
|
|
15
37
|
/**
|
|
@@ -18,6 +40,36 @@ export declare const filterVars: (vars: Record<string, string | null | undefined
|
|
|
18
40
|
* every other subprocess this plugin could help) unlaunchable.
|
|
19
41
|
*/
|
|
20
42
|
export declare const repairPath: () => string;
|
|
43
|
+
/**
|
|
44
|
+
* The PATH used in the direnv baseline. Deliberately does NOT read
|
|
45
|
+
* process.env.PATH or HOST_PATH: the plugin applies the devshell PATH (and
|
|
46
|
+
* the devshell exports HOST_PATH) into process.env, so reading either back
|
|
47
|
+
* would feed the plugin's own output into the next baseline and oscillate.
|
|
48
|
+
* Built from stable per-machine locations only, so the export stays a pure
|
|
49
|
+
* function of the devshell. Custom interactive-shell PATH entries are not
|
|
50
|
+
* part of it by design; the devshell's own paths are prepended by the export.
|
|
51
|
+
*/
|
|
52
|
+
export declare const baselinePath: () => string;
|
|
53
|
+
/**
|
|
54
|
+
* The environment `direnv export json` is invoked with.
|
|
55
|
+
*
|
|
56
|
+
* direnv computes its export as a *diff against the invoking environment*, so
|
|
57
|
+
* the invoking environment must be STABLE and independent of what this plugin
|
|
58
|
+
* previously applied:
|
|
59
|
+
*
|
|
60
|
+
* - Invoking direnv with vars we applied on an earlier reload makes direnv
|
|
61
|
+
* omit them from the export; the plugin would read that as "dropped",
|
|
62
|
+
* delete them, and the next export would re-add them — oscillating (`+N` /
|
|
63
|
+
* `-N`) on every no-op reload.
|
|
64
|
+
* - Conversely, stripping applied vars from the real environment is wrong
|
|
65
|
+
* too: removing `PATH` makes the devshell evaluate against an empty PATH,
|
|
66
|
+
* exporting a PATH with no system/profile entries at all.
|
|
67
|
+
*
|
|
68
|
+
* So direnv always runs against this fixed, minimal baseline — the export
|
|
69
|
+
* becomes a pure function of the devshell itself, like a fresh login shell
|
|
70
|
+
* entering the project directory.
|
|
71
|
+
*/
|
|
72
|
+
export declare const exportBaseline: () => NodeJS.ProcessEnv;
|
|
21
73
|
/**
|
|
22
74
|
* Return the first direnv candidate that responds to `direnv version`, or
|
|
23
75
|
* null. Pure w.r.t. module state so it stays testable.
|
|
@@ -25,6 +77,42 @@ export declare const repairPath: () => string;
|
|
|
25
77
|
export declare const probeDirenv: (candidates: string[], exec?: (file: string, args: string[]) => Promise<unknown>) => Promise<string | null>;
|
|
26
78
|
/** Find the nearest .envrc at or above `start`, not looking past `stopAt`. */
|
|
27
79
|
export declare const nearestEnvrc: (start: string, stopAt: string | null) => string | null;
|
|
80
|
+
/**
|
|
81
|
+
* Shared ownership of the global process.env across plugin instances.
|
|
82
|
+
*
|
|
83
|
+
* One server process can host several locations (projects), each with its own
|
|
84
|
+
* plugin instance and devshell, but process.env is global. If every instance
|
|
85
|
+
* tracked only its own keys, instance A dropping a key it no longer exports
|
|
86
|
+
* would delete it even while instance B still exports it — parallel sessions
|
|
87
|
+
* in different projects would flap (`-N` on A's reload, `+N` on B's).
|
|
88
|
+
*
|
|
89
|
+
* So every applied key records WHICH locations (owner directories) export it
|
|
90
|
+
* and the value each wants, plus the value predating the first claim. A key
|
|
91
|
+
* leaves process.env only when no instance owns it anymore, and then reverts
|
|
92
|
+
* to its pre-plugin value instead of vanishing. Conflicting values for one
|
|
93
|
+
* key across projects stay last-writer-wins (a single global env cannot hold
|
|
94
|
+
* both); the cwd-scoped shell hook remains the precise per-shell mechanism.
|
|
95
|
+
*/
|
|
96
|
+
export type SharedEnvState = {
|
|
97
|
+
/** key -> (owner directory -> wanted value); insertion-ordered, last wins */
|
|
98
|
+
owners: Map<string, Map<string, string>>;
|
|
99
|
+
/** key -> value from before the first claim (undefined = was absent) */
|
|
100
|
+
originals: Map<string, string | undefined>;
|
|
101
|
+
};
|
|
102
|
+
export declare const createSharedEnvState: () => SharedEnvState;
|
|
103
|
+
/**
|
|
104
|
+
* Claim `filteredVars` for `owner` and reconcile `env`, honouring other
|
|
105
|
+
* owners' claims. Pure w.r.t. module state (all shared state is passed in)
|
|
106
|
+
* so parallel instances are testable without a server.
|
|
107
|
+
*/
|
|
108
|
+
export declare const reconcileSharedEnv: (state: SharedEnvState, env: NodeJS.ProcessEnv, owner: string, prevOwned: Set<string>, filteredVars: Record<string, string>) => {
|
|
109
|
+
added: number;
|
|
110
|
+
changed: number;
|
|
111
|
+
removed: number;
|
|
112
|
+
nextOwned: Set<string>;
|
|
113
|
+
};
|
|
114
|
+
/** Release every key `owner` holds (plugin teardown); survivors keep theirs. */
|
|
115
|
+
export declare const releaseAllSharedEnv: (state: SharedEnvState, env: NodeJS.ProcessEnv, owner: string, owned: Set<string>) => void;
|
|
28
116
|
declare const _default: Plugin.Plugin;
|
|
29
117
|
export default _default;
|
|
30
118
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AA0F5C,0DAA0D;AAC1D,eAAO,MAAM,QAAQ,cAapB,CAAA;AAED;+DAC+D;AAC/D,eAAO,MAAM,gBAAgB,gBASR,CAAA;AAErB,qEAAqE;AACrE,eAAO,MAAM,WAAW,QAAO,MAAM,EASpC,CAAA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAYjG,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,QAAO,MAO7B,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,QAAO,MAY/B,CAAA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,cAAc,QAAO,MAAM,CAAC,UAiBxC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,GACtB,YAAY,MAAM,EAAE,EACpB,OAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,OAAO,CAAyD,KAC/G,OAAO,CAAC,MAAM,GAAG,IAAI,CAUvB,CAAA;AAUD,8EAA8E;AAC9E,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,EAAE,QAAQ,MAAM,GAAG,IAAI,KAAG,MAAM,GAAG,IAW5E,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,6EAA6E;IAC7E,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACxC,wEAAwE;IACxE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;CAC3C,CAAA;AAED,eAAO,MAAM,oBAAoB,QAAO,cAGtC,CAAA;AAkDF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,OAAO,cAAc,EACrB,KAAK,MAAM,CAAC,UAAU,EACtB,OAAO,MAAM,EACb,WAAW,GAAG,CAAC,MAAM,CAAC,EACtB,cAAc,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACnC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAmC3E,CAAA;AAED,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,cAAc,EACrB,KAAK,MAAM,CAAC,UAAU,EACtB,OAAO,MAAM,EACb,OAAO,GAAG,CAAC,MAAM,CAAC,KACjB,IAGF,CAAA;;AAgCD,wBA0UE"}
|
package/dist/index.js
CHANGED
|
@@ -21,8 +21,10 @@ import { promisify } from "node:util";
|
|
|
21
21
|
* (e.g. after the user edits the flake in their own editor/terminal)
|
|
22
22
|
* - Injects the latest direnv export into every spawned shell via the
|
|
23
23
|
* `shell.create.before` hook (primary mechanism)
|
|
24
|
-
* - Reconciles process.env as a fallback for other subprocesses (LSP, MCP)
|
|
25
|
-
* *
|
|
24
|
+
* - Reconciles process.env as a fallback for other subprocesses (LSP, MCP),
|
|
25
|
+
* *removing* dropped keys — with cross-instance ownership so parallel
|
|
26
|
+
* projects can't delete each other's live vars, and fully released keys
|
|
27
|
+
* revert to their pre-plugin values
|
|
26
28
|
* - Logs outcomes with a `direnv:` prefix (blocked .envrc is always reported)
|
|
27
29
|
* - Silently skips if direnv is not installed or .envrc is missing
|
|
28
30
|
*
|
|
@@ -87,18 +89,46 @@ export const stripPoison = () => {
|
|
|
87
89
|
}
|
|
88
90
|
return removed;
|
|
89
91
|
};
|
|
92
|
+
/**
|
|
93
|
+
* The environment `direnv export json` is invoked with.
|
|
94
|
+
*
|
|
95
|
+
* direnv computes its export as a *diff against the invoking environment*, so
|
|
96
|
+
* the invoking environment must be STABLE and independent of what this plugin
|
|
97
|
+
* previously applied:
|
|
98
|
+
*
|
|
99
|
+
* - Invoking direnv with vars we applied on an earlier reload makes direnv
|
|
100
|
+
* omit them from the export; the plugin would read that as "dropped",
|
|
101
|
+
* delete them, and the next export would re-add them — oscillating (`+N` /
|
|
102
|
+
* `-N`) on every no-op reload.
|
|
103
|
+
* - Conversely, stripping applied vars from the real environment is wrong
|
|
104
|
+
* too: removing `PATH` makes the devshell evaluate against an empty PATH,
|
|
105
|
+
* exporting a PATH with no system/profile entries at all.
|
|
106
|
+
*
|
|
107
|
+
* So direnv always runs against this fixed, minimal baseline — the export
|
|
108
|
+
* becomes a pure function of the devshell itself, like a fresh login shell
|
|
109
|
+
* entering the project directory.
|
|
110
|
+
*/
|
|
90
111
|
/**
|
|
91
112
|
* Filter a `direnv export json` payload down to variables that are safe to
|
|
92
|
-
* apply: valid POSIX names only (drops phantom entries like `export PATH`)
|
|
93
|
-
*
|
|
113
|
+
* apply: valid POSIX names only (drops phantom entries like `export PATH`),
|
|
114
|
+
* no script-valued vars (drops nix's `shellHook` and friends), and no direnv
|
|
115
|
+
* bookkeeping vars (`DIRENV_DIFF`, `DIRENV_WATCHES`, … churn on every
|
|
116
|
+
* evaluation and exist for the wrapping shell's eval, not for consumers —
|
|
117
|
+
* applying them makes reloads oscillate and pollutes spawned shells).
|
|
94
118
|
*/
|
|
95
119
|
export const filterVars = (vars) => {
|
|
96
120
|
const safe = {};
|
|
97
121
|
for (const [key, value] of Object.entries(vars)) {
|
|
98
122
|
if (value == null)
|
|
99
123
|
continue;
|
|
124
|
+
// `__proto__` passes VALID_NAME but assignment would hit the prototype
|
|
125
|
+
// setter instead of creating an env entry — never safe to apply.
|
|
126
|
+
if (key === "__proto__")
|
|
127
|
+
continue;
|
|
100
128
|
if (!VALID_NAME.test(key) || SCRIPT_VARS.has(key))
|
|
101
129
|
continue;
|
|
130
|
+
if (key.startsWith("DIRENV_"))
|
|
131
|
+
continue;
|
|
102
132
|
safe[key] = value;
|
|
103
133
|
}
|
|
104
134
|
return safe;
|
|
@@ -117,6 +147,62 @@ export const repairPath = () => {
|
|
|
117
147
|
console.warn(`direnv: repaired corrupted PATH (was ${JSON.stringify(current)})`);
|
|
118
148
|
return fallback;
|
|
119
149
|
};
|
|
150
|
+
/**
|
|
151
|
+
* The PATH used in the direnv baseline. Deliberately does NOT read
|
|
152
|
+
* process.env.PATH or HOST_PATH: the plugin applies the devshell PATH (and
|
|
153
|
+
* the devshell exports HOST_PATH) into process.env, so reading either back
|
|
154
|
+
* would feed the plugin's own output into the next baseline and oscillate.
|
|
155
|
+
* Built from stable per-machine locations only, so the export stays a pure
|
|
156
|
+
* function of the devshell. Custom interactive-shell PATH entries are not
|
|
157
|
+
* part of it by design; the devshell's own paths are prepended by the export.
|
|
158
|
+
*/
|
|
159
|
+
export const baselinePath = () => {
|
|
160
|
+
const parts = [];
|
|
161
|
+
if (process.env.HOME)
|
|
162
|
+
parts.push(`${process.env.HOME}/.nix-profile/bin`);
|
|
163
|
+
if (process.env.USER)
|
|
164
|
+
parts.push(`/etc/profiles/per-user/${process.env.USER}/bin`);
|
|
165
|
+
parts.push("/nix/var/nix/profiles/default/bin", "/run/current-system/sw/bin", "/opt/homebrew/bin", "/usr/local/bin", "/usr/bin:/bin:/usr/sbin:/sbin");
|
|
166
|
+
return parts.join(":");
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* The environment `direnv export json` is invoked with.
|
|
170
|
+
*
|
|
171
|
+
* direnv computes its export as a *diff against the invoking environment*, so
|
|
172
|
+
* the invoking environment must be STABLE and independent of what this plugin
|
|
173
|
+
* previously applied:
|
|
174
|
+
*
|
|
175
|
+
* - Invoking direnv with vars we applied on an earlier reload makes direnv
|
|
176
|
+
* omit them from the export; the plugin would read that as "dropped",
|
|
177
|
+
* delete them, and the next export would re-add them — oscillating (`+N` /
|
|
178
|
+
* `-N`) on every no-op reload.
|
|
179
|
+
* - Conversely, stripping applied vars from the real environment is wrong
|
|
180
|
+
* too: removing `PATH` makes the devshell evaluate against an empty PATH,
|
|
181
|
+
* exporting a PATH with no system/profile entries at all.
|
|
182
|
+
*
|
|
183
|
+
* So direnv always runs against this fixed, minimal baseline — the export
|
|
184
|
+
* becomes a pure function of the devshell itself, like a fresh login shell
|
|
185
|
+
* entering the project directory.
|
|
186
|
+
*/
|
|
187
|
+
export const exportBaseline = () => {
|
|
188
|
+
const wanted = [
|
|
189
|
+
"HOME",
|
|
190
|
+
"USER",
|
|
191
|
+
"TERM",
|
|
192
|
+
"TMPDIR",
|
|
193
|
+
"SHELL",
|
|
194
|
+
"LANG",
|
|
195
|
+
];
|
|
196
|
+
const baseline = {};
|
|
197
|
+
for (const key of wanted) {
|
|
198
|
+
const value = process.env[key];
|
|
199
|
+
if (value !== undefined)
|
|
200
|
+
baseline[key] = value;
|
|
201
|
+
}
|
|
202
|
+
// never derived from (possibly corrupted or plugin-applied) process.env.PATH
|
|
203
|
+
baseline.PATH = baselinePath();
|
|
204
|
+
return baseline;
|
|
205
|
+
};
|
|
120
206
|
/**
|
|
121
207
|
* Return the first direnv candidate that responds to `direnv version`, or
|
|
122
208
|
* null. Pure w.r.t. module state so it stays testable.
|
|
@@ -157,6 +243,103 @@ export const nearestEnvrc = (start, stopAt) => {
|
|
|
157
243
|
current = parent;
|
|
158
244
|
}
|
|
159
245
|
};
|
|
246
|
+
export const createSharedEnvState = () => ({
|
|
247
|
+
owners: new Map(),
|
|
248
|
+
originals: new Map(),
|
|
249
|
+
});
|
|
250
|
+
/** module singleton used by the live plugin instances in this process */
|
|
251
|
+
const sharedEnv = createSharedEnvState();
|
|
252
|
+
/** read that ignores inherited properties (`"toString" in env` is true) */
|
|
253
|
+
const readEnvKey = (env, key) => Object.hasOwn(env, key) ? env[key] : undefined;
|
|
254
|
+
const lastOwnerValue = (owned) => {
|
|
255
|
+
if (!owned || owned.size === 0)
|
|
256
|
+
return undefined;
|
|
257
|
+
let last = "";
|
|
258
|
+
for (const value of owned.values())
|
|
259
|
+
last = value;
|
|
260
|
+
return last;
|
|
261
|
+
};
|
|
262
|
+
/**
|
|
263
|
+
* Drop one owner's claim on a key, repairing process.env to match whoever
|
|
264
|
+
* (if anyone) still owns it. Returns how the environment transitioned.
|
|
265
|
+
*/
|
|
266
|
+
const releaseOneKey = (state, env, owner, key) => {
|
|
267
|
+
const owned = state.owners.get(key);
|
|
268
|
+
if (owned) {
|
|
269
|
+
owned.delete(owner);
|
|
270
|
+
if (owned.size === 0)
|
|
271
|
+
state.owners.delete(key);
|
|
272
|
+
}
|
|
273
|
+
const survivor = lastOwnerValue(state.owners.get(key));
|
|
274
|
+
if (survivor === undefined) {
|
|
275
|
+
if (readEnvKey(env, key) !== undefined) {
|
|
276
|
+
const original = state.originals.get(key);
|
|
277
|
+
if (original === undefined)
|
|
278
|
+
delete env[key];
|
|
279
|
+
else
|
|
280
|
+
env[key] = original;
|
|
281
|
+
state.originals.delete(key);
|
|
282
|
+
return "removed";
|
|
283
|
+
}
|
|
284
|
+
state.originals.delete(key);
|
|
285
|
+
return "unchanged";
|
|
286
|
+
}
|
|
287
|
+
if (readEnvKey(env, key) !== survivor) {
|
|
288
|
+
env[key] = survivor;
|
|
289
|
+
return "changed";
|
|
290
|
+
}
|
|
291
|
+
return "unchanged";
|
|
292
|
+
};
|
|
293
|
+
/**
|
|
294
|
+
* Claim `filteredVars` for `owner` and reconcile `env`, honouring other
|
|
295
|
+
* owners' claims. Pure w.r.t. module state (all shared state is passed in)
|
|
296
|
+
* so parallel instances are testable without a server.
|
|
297
|
+
*/
|
|
298
|
+
export const reconcileSharedEnv = (state, env, owner, prevOwned, filteredVars) => {
|
|
299
|
+
let added = 0;
|
|
300
|
+
let changed = 0;
|
|
301
|
+
let removed = 0;
|
|
302
|
+
// 1. Release keys this owner no longer exports. Keys still owned elsewhere
|
|
303
|
+
// survive (restoring the surviving owner's value); only fully unowned
|
|
304
|
+
// keys revert to their pre-plugin values. `hasOwn` (not `in`) so
|
|
305
|
+
// prototype-named keys can't leak by looking "kept".
|
|
306
|
+
for (const key of prevOwned) {
|
|
307
|
+
if (Object.hasOwn(filteredVars, key))
|
|
308
|
+
continue;
|
|
309
|
+
const result = releaseOneKey(state, env, owner, key);
|
|
310
|
+
if (result === "removed")
|
|
311
|
+
removed++;
|
|
312
|
+
else if (result === "changed")
|
|
313
|
+
changed++;
|
|
314
|
+
}
|
|
315
|
+
// 2. Claim + apply current exports (conflicting values: last writer wins).
|
|
316
|
+
const nextOwned = new Set();
|
|
317
|
+
for (const [key, value] of Object.entries(filteredVars)) {
|
|
318
|
+
let owned = state.owners.get(key);
|
|
319
|
+
if (!owned) {
|
|
320
|
+
owned = new Map();
|
|
321
|
+
state.owners.set(key, owned);
|
|
322
|
+
if (!state.originals.has(key))
|
|
323
|
+
state.originals.set(key, readEnvKey(env, key));
|
|
324
|
+
}
|
|
325
|
+
owned.delete(owner);
|
|
326
|
+
owned.set(owner, value);
|
|
327
|
+
const current = readEnvKey(env, key);
|
|
328
|
+
if (current === undefined)
|
|
329
|
+
added++;
|
|
330
|
+
else if (current !== value)
|
|
331
|
+
changed++;
|
|
332
|
+
env[key] = value;
|
|
333
|
+
nextOwned.add(key);
|
|
334
|
+
}
|
|
335
|
+
return { added, changed, removed, nextOwned };
|
|
336
|
+
};
|
|
337
|
+
/** Release every key `owner` holds (plugin teardown); survivors keep theirs. */
|
|
338
|
+
export const releaseAllSharedEnv = (state, env, owner, owned) => {
|
|
339
|
+
for (const key of owned)
|
|
340
|
+
releaseOneKey(state, env, owner, key);
|
|
341
|
+
owned.clear();
|
|
342
|
+
};
|
|
160
343
|
/**
|
|
161
344
|
* Strip poison and repair PATH. Runs before every direnv invocation so a
|
|
162
345
|
* daemon that gets corrupted mid-flight heals itself on the next reload.
|
|
@@ -171,11 +354,12 @@ const sanitize = () => {
|
|
|
171
354
|
repairPath();
|
|
172
355
|
return stripped.length > 0 || process.env.PATH !== before;
|
|
173
356
|
};
|
|
174
|
-
const runText = async (file, args, cwd) => {
|
|
357
|
+
const runText = async (file, args, cwd, env) => {
|
|
175
358
|
const { stdout } = await run(file, args, {
|
|
176
359
|
cwd,
|
|
177
360
|
encoding: "utf8",
|
|
178
361
|
maxBuffer: 10 * 1024 * 1024,
|
|
362
|
+
...(env ? { env } : {}),
|
|
179
363
|
});
|
|
180
364
|
return stdout;
|
|
181
365
|
};
|
|
@@ -189,9 +373,10 @@ export default Plugin.define({
|
|
|
189
373
|
*/
|
|
190
374
|
const loadedSessions = new Set();
|
|
191
375
|
/**
|
|
192
|
-
* Keys
|
|
193
|
-
*
|
|
194
|
-
*
|
|
376
|
+
* Keys this instance has claimed in the shared process.env registry.
|
|
377
|
+
* process.env itself is global across locations in the server process —
|
|
378
|
+
* see SharedEnvState — so removal goes through shared ownership and never
|
|
379
|
+
* deletes a key another project still exports.
|
|
195
380
|
*/
|
|
196
381
|
const appliedKeys = new Set();
|
|
197
382
|
/** latest successful `direnv export json` payload, injected into spawned shells */
|
|
@@ -268,7 +453,9 @@ export default Plugin.define({
|
|
|
268
453
|
}
|
|
269
454
|
let jsonText;
|
|
270
455
|
try {
|
|
271
|
-
|
|
456
|
+
// See exportBaseline: a fixed baseline keeps the direnv diff stable
|
|
457
|
+
// (no oscillation) and the exported PATH well-formed.
|
|
458
|
+
jsonText = await runText(direnv, ["export", "json"], dir, exportBaseline());
|
|
272
459
|
}
|
|
273
460
|
catch (error) {
|
|
274
461
|
const stderr = error && typeof error === "object" && "stderr" in error
|
|
@@ -284,33 +471,28 @@ export default Plugin.define({
|
|
|
284
471
|
}
|
|
285
472
|
const parsed = jsonText.trim() ? JSON.parse(jsonText) : {};
|
|
286
473
|
const newVars = parsed && typeof parsed === "object" ? parsed : {};
|
|
287
|
-
|
|
288
|
-
//
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
296
|
-
// 2. Apply current vars, counting additions and value changes.
|
|
474
|
+
const filteredVars = filterVars(newVars);
|
|
475
|
+
// 1. Release vars this devshell no longer exports (or that are no
|
|
476
|
+
// longer safe to apply). Shared ownership keeps keys alive while
|
|
477
|
+
// another project still exports them; fully released keys revert
|
|
478
|
+
// to their pre-plugin values. direnv's explicit `null` unset
|
|
479
|
+
// signals land here too (filterVars already dropped them).
|
|
480
|
+
// 2. Claim + apply current vars, counting additions and value changes
|
|
481
|
+
// (conflicting values across projects: last writer wins).
|
|
297
482
|
// filterVars drops invalid names (e.g. a phantom `export PATH`
|
|
298
483
|
// entry) and script-valued vars (e.g. nix's `shellHook`) — they
|
|
299
484
|
// corrupt subprocess environments instead of configuring them.
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
outcome.added++;
|
|
305
|
-
else if (current !== value)
|
|
306
|
-
outcome.changed++;
|
|
307
|
-
process.env[key] = value;
|
|
308
|
-
nextApplied.add(key);
|
|
309
|
-
}
|
|
485
|
+
const counts = reconcileSharedEnv(sharedEnv, process.env, directory, appliedKeys, filteredVars);
|
|
486
|
+
outcome.added += counts.added;
|
|
487
|
+
outcome.changed += counts.changed;
|
|
488
|
+
outcome.removed += counts.removed;
|
|
310
489
|
appliedKeys.clear();
|
|
311
|
-
for (const key of
|
|
490
|
+
for (const key of counts.nextOwned)
|
|
312
491
|
appliedKeys.add(key);
|
|
313
|
-
|
|
492
|
+
// Inject only the filtered set: the raw payload can carry null
|
|
493
|
+
// unset-signals, and the shell hook writes values verbatim into
|
|
494
|
+
// spawned shell environments (which must be strings).
|
|
495
|
+
currentVars = filterVars(newVars);
|
|
314
496
|
return outcome;
|
|
315
497
|
}
|
|
316
498
|
catch {
|
|
@@ -429,6 +611,9 @@ export default Plugin.define({
|
|
|
429
611
|
properties: {},
|
|
430
612
|
additionalProperties: false,
|
|
431
613
|
},
|
|
614
|
+
// without this the tool registers as a top-level `reload` instead of
|
|
615
|
+
// joining the `direnv` namespace registered above
|
|
616
|
+
options: { namespace: "direnv" },
|
|
432
617
|
execute: async () => {
|
|
433
618
|
const outcome = await reloadEnv();
|
|
434
619
|
logOutcome(outcome, { initial: false });
|
|
@@ -484,6 +669,9 @@ export default Plugin.define({
|
|
|
484
669
|
controller.abort();
|
|
485
670
|
if (reloadTimer)
|
|
486
671
|
clearTimeout(reloadTimer);
|
|
672
|
+
// Release our shared-env claims so parallel projects keep their values
|
|
673
|
+
// and fully released keys revert to pre-plugin values.
|
|
674
|
+
releaseAllSharedEnv(sharedEnv, process.env, directory, appliedKeys);
|
|
487
675
|
void shellRegistration.dispose();
|
|
488
676
|
void toolRegistration.dispose();
|
|
489
677
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -22,8 +22,10 @@ import { promisify } from "node:util"
|
|
|
22
22
|
* (e.g. after the user edits the flake in their own editor/terminal)
|
|
23
23
|
* - Injects the latest direnv export into every spawned shell via the
|
|
24
24
|
* `shell.create.before` hook (primary mechanism)
|
|
25
|
-
* - Reconciles process.env as a fallback for other subprocesses (LSP, MCP)
|
|
26
|
-
* *
|
|
25
|
+
* - Reconciles process.env as a fallback for other subprocesses (LSP, MCP),
|
|
26
|
+
* *removing* dropped keys — with cross-instance ownership so parallel
|
|
27
|
+
* projects can't delete each other's live vars, and fully released keys
|
|
28
|
+
* revert to their pre-plugin values
|
|
27
29
|
* - Logs outcomes with a `direnv:` prefix (blocked .envrc is always reported)
|
|
28
30
|
* - Silently skips if direnv is not installed or .envrc is missing
|
|
29
31
|
*
|
|
@@ -127,16 +129,42 @@ export const stripPoison = (): string[] => {
|
|
|
127
129
|
return removed
|
|
128
130
|
}
|
|
129
131
|
|
|
132
|
+
/**
|
|
133
|
+
* The environment `direnv export json` is invoked with.
|
|
134
|
+
*
|
|
135
|
+
* direnv computes its export as a *diff against the invoking environment*, so
|
|
136
|
+
* the invoking environment must be STABLE and independent of what this plugin
|
|
137
|
+
* previously applied:
|
|
138
|
+
*
|
|
139
|
+
* - Invoking direnv with vars we applied on an earlier reload makes direnv
|
|
140
|
+
* omit them from the export; the plugin would read that as "dropped",
|
|
141
|
+
* delete them, and the next export would re-add them — oscillating (`+N` /
|
|
142
|
+
* `-N`) on every no-op reload.
|
|
143
|
+
* - Conversely, stripping applied vars from the real environment is wrong
|
|
144
|
+
* too: removing `PATH` makes the devshell evaluate against an empty PATH,
|
|
145
|
+
* exporting a PATH with no system/profile entries at all.
|
|
146
|
+
*
|
|
147
|
+
* So direnv always runs against this fixed, minimal baseline — the export
|
|
148
|
+
* becomes a pure function of the devshell itself, like a fresh login shell
|
|
149
|
+
* entering the project directory.
|
|
150
|
+
*/
|
|
130
151
|
/**
|
|
131
152
|
* Filter a `direnv export json` payload down to variables that are safe to
|
|
132
|
-
* apply: valid POSIX names only (drops phantom entries like `export PATH`)
|
|
133
|
-
*
|
|
153
|
+
* apply: valid POSIX names only (drops phantom entries like `export PATH`),
|
|
154
|
+
* no script-valued vars (drops nix's `shellHook` and friends), and no direnv
|
|
155
|
+
* bookkeeping vars (`DIRENV_DIFF`, `DIRENV_WATCHES`, … churn on every
|
|
156
|
+
* evaluation and exist for the wrapping shell's eval, not for consumers —
|
|
157
|
+
* applying them makes reloads oscillate and pollutes spawned shells).
|
|
134
158
|
*/
|
|
135
159
|
export const filterVars = (vars: Record<string, string | null | undefined>): Record<string, string> => {
|
|
136
160
|
const safe: Record<string, string> = {}
|
|
137
161
|
for (const [key, value] of Object.entries(vars)) {
|
|
138
162
|
if (value == null) continue
|
|
163
|
+
// `__proto__` passes VALID_NAME but assignment would hit the prototype
|
|
164
|
+
// setter instead of creating an env entry — never safe to apply.
|
|
165
|
+
if (key === "__proto__") continue
|
|
139
166
|
if (!VALID_NAME.test(key) || SCRIPT_VARS.has(key)) continue
|
|
167
|
+
if (key.startsWith("DIRENV_")) continue
|
|
140
168
|
safe[key] = value
|
|
141
169
|
}
|
|
142
170
|
return safe
|
|
@@ -156,6 +184,67 @@ export const repairPath = (): string => {
|
|
|
156
184
|
return fallback
|
|
157
185
|
}
|
|
158
186
|
|
|
187
|
+
/**
|
|
188
|
+
* The PATH used in the direnv baseline. Deliberately does NOT read
|
|
189
|
+
* process.env.PATH or HOST_PATH: the plugin applies the devshell PATH (and
|
|
190
|
+
* the devshell exports HOST_PATH) into process.env, so reading either back
|
|
191
|
+
* would feed the plugin's own output into the next baseline and oscillate.
|
|
192
|
+
* Built from stable per-machine locations only, so the export stays a pure
|
|
193
|
+
* function of the devshell. Custom interactive-shell PATH entries are not
|
|
194
|
+
* part of it by design; the devshell's own paths are prepended by the export.
|
|
195
|
+
*/
|
|
196
|
+
export const baselinePath = (): string => {
|
|
197
|
+
const parts: string[] = []
|
|
198
|
+
if (process.env.HOME) parts.push(`${process.env.HOME}/.nix-profile/bin`)
|
|
199
|
+
if (process.env.USER) parts.push(`/etc/profiles/per-user/${process.env.USER}/bin`)
|
|
200
|
+
parts.push(
|
|
201
|
+
"/nix/var/nix/profiles/default/bin",
|
|
202
|
+
"/run/current-system/sw/bin",
|
|
203
|
+
"/opt/homebrew/bin",
|
|
204
|
+
"/usr/local/bin",
|
|
205
|
+
"/usr/bin:/bin:/usr/sbin:/sbin",
|
|
206
|
+
)
|
|
207
|
+
return parts.join(":")
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* The environment `direnv export json` is invoked with.
|
|
212
|
+
*
|
|
213
|
+
* direnv computes its export as a *diff against the invoking environment*, so
|
|
214
|
+
* the invoking environment must be STABLE and independent of what this plugin
|
|
215
|
+
* previously applied:
|
|
216
|
+
*
|
|
217
|
+
* - Invoking direnv with vars we applied on an earlier reload makes direnv
|
|
218
|
+
* omit them from the export; the plugin would read that as "dropped",
|
|
219
|
+
* delete them, and the next export would re-add them — oscillating (`+N` /
|
|
220
|
+
* `-N`) on every no-op reload.
|
|
221
|
+
* - Conversely, stripping applied vars from the real environment is wrong
|
|
222
|
+
* too: removing `PATH` makes the devshell evaluate against an empty PATH,
|
|
223
|
+
* exporting a PATH with no system/profile entries at all.
|
|
224
|
+
*
|
|
225
|
+
* So direnv always runs against this fixed, minimal baseline — the export
|
|
226
|
+
* becomes a pure function of the devshell itself, like a fresh login shell
|
|
227
|
+
* entering the project directory.
|
|
228
|
+
*/
|
|
229
|
+
export const exportBaseline = (): NodeJS.ProcessEnv => {
|
|
230
|
+
const wanted: Array<keyof NodeJS.ProcessEnv> = [
|
|
231
|
+
"HOME",
|
|
232
|
+
"USER",
|
|
233
|
+
"TERM",
|
|
234
|
+
"TMPDIR",
|
|
235
|
+
"SHELL",
|
|
236
|
+
"LANG",
|
|
237
|
+
]
|
|
238
|
+
const baseline: NodeJS.ProcessEnv = {}
|
|
239
|
+
for (const key of wanted) {
|
|
240
|
+
const value = process.env[key]
|
|
241
|
+
if (value !== undefined) baseline[key] = value
|
|
242
|
+
}
|
|
243
|
+
// never derived from (possibly corrupted or plugin-applied) process.env.PATH
|
|
244
|
+
baseline.PATH = baselinePath()
|
|
245
|
+
return baseline
|
|
246
|
+
}
|
|
247
|
+
|
|
159
248
|
/**
|
|
160
249
|
* Return the first direnv candidate that responds to `direnv version`, or
|
|
161
250
|
* null. Pure w.r.t. module state so it stays testable.
|
|
@@ -197,6 +286,141 @@ export const nearestEnvrc = (start: string, stopAt: string | null): string | nul
|
|
|
197
286
|
}
|
|
198
287
|
}
|
|
199
288
|
|
|
289
|
+
/**
|
|
290
|
+
* Shared ownership of the global process.env across plugin instances.
|
|
291
|
+
*
|
|
292
|
+
* One server process can host several locations (projects), each with its own
|
|
293
|
+
* plugin instance and devshell, but process.env is global. If every instance
|
|
294
|
+
* tracked only its own keys, instance A dropping a key it no longer exports
|
|
295
|
+
* would delete it even while instance B still exports it — parallel sessions
|
|
296
|
+
* in different projects would flap (`-N` on A's reload, `+N` on B's).
|
|
297
|
+
*
|
|
298
|
+
* So every applied key records WHICH locations (owner directories) export it
|
|
299
|
+
* and the value each wants, plus the value predating the first claim. A key
|
|
300
|
+
* leaves process.env only when no instance owns it anymore, and then reverts
|
|
301
|
+
* to its pre-plugin value instead of vanishing. Conflicting values for one
|
|
302
|
+
* key across projects stay last-writer-wins (a single global env cannot hold
|
|
303
|
+
* both); the cwd-scoped shell hook remains the precise per-shell mechanism.
|
|
304
|
+
*/
|
|
305
|
+
export type SharedEnvState = {
|
|
306
|
+
/** key -> (owner directory -> wanted value); insertion-ordered, last wins */
|
|
307
|
+
owners: Map<string, Map<string, string>>
|
|
308
|
+
/** key -> value from before the first claim (undefined = was absent) */
|
|
309
|
+
originals: Map<string, string | undefined>
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export const createSharedEnvState = (): SharedEnvState => ({
|
|
313
|
+
owners: new Map(),
|
|
314
|
+
originals: new Map(),
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
/** module singleton used by the live plugin instances in this process */
|
|
318
|
+
const sharedEnv: SharedEnvState = createSharedEnvState()
|
|
319
|
+
|
|
320
|
+
/** read that ignores inherited properties (`"toString" in env` is true) */
|
|
321
|
+
const readEnvKey = (env: NodeJS.ProcessEnv, key: string): string | undefined =>
|
|
322
|
+
Object.hasOwn(env, key) ? env[key] : undefined
|
|
323
|
+
|
|
324
|
+
const lastOwnerValue = (owned: Map<string, string> | undefined): string | undefined => {
|
|
325
|
+
if (!owned || owned.size === 0) return undefined
|
|
326
|
+
let last = ""
|
|
327
|
+
for (const value of owned.values()) last = value
|
|
328
|
+
return last
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Drop one owner's claim on a key, repairing process.env to match whoever
|
|
333
|
+
* (if anyone) still owns it. Returns how the environment transitioned.
|
|
334
|
+
*/
|
|
335
|
+
const releaseOneKey = (
|
|
336
|
+
state: SharedEnvState,
|
|
337
|
+
env: NodeJS.ProcessEnv,
|
|
338
|
+
owner: string,
|
|
339
|
+
key: string,
|
|
340
|
+
): "removed" | "changed" | "unchanged" => {
|
|
341
|
+
const owned = state.owners.get(key)
|
|
342
|
+
if (owned) {
|
|
343
|
+
owned.delete(owner)
|
|
344
|
+
if (owned.size === 0) state.owners.delete(key)
|
|
345
|
+
}
|
|
346
|
+
const survivor = lastOwnerValue(state.owners.get(key))
|
|
347
|
+
if (survivor === undefined) {
|
|
348
|
+
if (readEnvKey(env, key) !== undefined) {
|
|
349
|
+
const original = state.originals.get(key)
|
|
350
|
+
if (original === undefined) delete env[key]
|
|
351
|
+
else env[key] = original
|
|
352
|
+
state.originals.delete(key)
|
|
353
|
+
return "removed"
|
|
354
|
+
}
|
|
355
|
+
state.originals.delete(key)
|
|
356
|
+
return "unchanged"
|
|
357
|
+
}
|
|
358
|
+
if (readEnvKey(env, key) !== survivor) {
|
|
359
|
+
env[key] = survivor
|
|
360
|
+
return "changed"
|
|
361
|
+
}
|
|
362
|
+
return "unchanged"
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Claim `filteredVars` for `owner` and reconcile `env`, honouring other
|
|
367
|
+
* owners' claims. Pure w.r.t. module state (all shared state is passed in)
|
|
368
|
+
* so parallel instances are testable without a server.
|
|
369
|
+
*/
|
|
370
|
+
export const reconcileSharedEnv = (
|
|
371
|
+
state: SharedEnvState,
|
|
372
|
+
env: NodeJS.ProcessEnv,
|
|
373
|
+
owner: string,
|
|
374
|
+
prevOwned: Set<string>,
|
|
375
|
+
filteredVars: Record<string, string>,
|
|
376
|
+
): { added: number; changed: number; removed: number; nextOwned: Set<string> } => {
|
|
377
|
+
let added = 0
|
|
378
|
+
let changed = 0
|
|
379
|
+
let removed = 0
|
|
380
|
+
|
|
381
|
+
// 1. Release keys this owner no longer exports. Keys still owned elsewhere
|
|
382
|
+
// survive (restoring the surviving owner's value); only fully unowned
|
|
383
|
+
// keys revert to their pre-plugin values. `hasOwn` (not `in`) so
|
|
384
|
+
// prototype-named keys can't leak by looking "kept".
|
|
385
|
+
for (const key of prevOwned) {
|
|
386
|
+
if (Object.hasOwn(filteredVars, key)) continue
|
|
387
|
+
const result = releaseOneKey(state, env, owner, key)
|
|
388
|
+
if (result === "removed") removed++
|
|
389
|
+
else if (result === "changed") changed++
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// 2. Claim + apply current exports (conflicting values: last writer wins).
|
|
393
|
+
const nextOwned = new Set<string>()
|
|
394
|
+
for (const [key, value] of Object.entries(filteredVars)) {
|
|
395
|
+
let owned = state.owners.get(key)
|
|
396
|
+
if (!owned) {
|
|
397
|
+
owned = new Map()
|
|
398
|
+
state.owners.set(key, owned)
|
|
399
|
+
if (!state.originals.has(key)) state.originals.set(key, readEnvKey(env, key))
|
|
400
|
+
}
|
|
401
|
+
owned.delete(owner)
|
|
402
|
+
owned.set(owner, value)
|
|
403
|
+
const current = readEnvKey(env, key)
|
|
404
|
+
if (current === undefined) added++
|
|
405
|
+
else if (current !== value) changed++
|
|
406
|
+
env[key] = value
|
|
407
|
+
nextOwned.add(key)
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return { added, changed, removed, nextOwned }
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/** Release every key `owner` holds (plugin teardown); survivors keep theirs. */
|
|
414
|
+
export const releaseAllSharedEnv = (
|
|
415
|
+
state: SharedEnvState,
|
|
416
|
+
env: NodeJS.ProcessEnv,
|
|
417
|
+
owner: string,
|
|
418
|
+
owned: Set<string>,
|
|
419
|
+
): void => {
|
|
420
|
+
for (const key of owned) releaseOneKey(state, env, owner, key)
|
|
421
|
+
owned.clear()
|
|
422
|
+
}
|
|
423
|
+
|
|
200
424
|
/**
|
|
201
425
|
* Strip poison and repair PATH. Runs before every direnv invocation so a
|
|
202
426
|
* daemon that gets corrupted mid-flight heals itself on the next reload.
|
|
@@ -212,11 +436,17 @@ const sanitize = (): boolean => {
|
|
|
212
436
|
return stripped.length > 0 || process.env.PATH !== before
|
|
213
437
|
}
|
|
214
438
|
|
|
215
|
-
const runText = async (
|
|
439
|
+
const runText = async (
|
|
440
|
+
file: string,
|
|
441
|
+
args: string[],
|
|
442
|
+
cwd: string,
|
|
443
|
+
env?: NodeJS.ProcessEnv,
|
|
444
|
+
) => {
|
|
216
445
|
const { stdout } = await run(file, args, {
|
|
217
446
|
cwd,
|
|
218
447
|
encoding: "utf8",
|
|
219
448
|
maxBuffer: 10 * 1024 * 1024,
|
|
449
|
+
...(env ? { env } : {}),
|
|
220
450
|
})
|
|
221
451
|
return stdout
|
|
222
452
|
}
|
|
@@ -234,9 +464,10 @@ export default Plugin.define({
|
|
|
234
464
|
const loadedSessions = new Set<string>()
|
|
235
465
|
|
|
236
466
|
/**
|
|
237
|
-
* Keys
|
|
238
|
-
*
|
|
239
|
-
*
|
|
467
|
+
* Keys this instance has claimed in the shared process.env registry.
|
|
468
|
+
* process.env itself is global across locations in the server process —
|
|
469
|
+
* see SharedEnvState — so removal goes through shared ownership and never
|
|
470
|
+
* deletes a key another project still exports.
|
|
240
471
|
*/
|
|
241
472
|
const appliedKeys = new Set<string>()
|
|
242
473
|
|
|
@@ -326,7 +557,9 @@ export default Plugin.define({
|
|
|
326
557
|
|
|
327
558
|
let jsonText: string
|
|
328
559
|
try {
|
|
329
|
-
|
|
560
|
+
// See exportBaseline: a fixed baseline keeps the direnv diff stable
|
|
561
|
+
// (no oscillation) and the exported PATH well-formed.
|
|
562
|
+
jsonText = await runText(direnv, ["export", "json"], dir, exportBaseline())
|
|
330
563
|
} catch (error: unknown) {
|
|
331
564
|
const stderr =
|
|
332
565
|
error && typeof error === "object" && "stderr" in error
|
|
@@ -344,32 +577,28 @@ export default Plugin.define({
|
|
|
344
577
|
const newVars: Record<string, string> =
|
|
345
578
|
parsed && typeof parsed === "object" ? parsed : {}
|
|
346
579
|
|
|
347
|
-
|
|
348
|
-
// direnv may also emit explicit `null` values to signal unsets.
|
|
349
|
-
for (const key of appliedKeys) {
|
|
350
|
-
const keep = key in newVars && newVars[key] != null
|
|
351
|
-
if (!keep && key in process.env) {
|
|
352
|
-
delete process.env[key]
|
|
353
|
-
outcome.removed++
|
|
354
|
-
}
|
|
355
|
-
}
|
|
580
|
+
const filteredVars = filterVars(newVars)
|
|
356
581
|
|
|
357
|
-
//
|
|
582
|
+
// 1. Release vars this devshell no longer exports (or that are no
|
|
583
|
+
// longer safe to apply). Shared ownership keeps keys alive while
|
|
584
|
+
// another project still exports them; fully released keys revert
|
|
585
|
+
// to their pre-plugin values. direnv's explicit `null` unset
|
|
586
|
+
// signals land here too (filterVars already dropped them).
|
|
587
|
+
// 2. Claim + apply current vars, counting additions and value changes
|
|
588
|
+
// (conflicting values across projects: last writer wins).
|
|
358
589
|
// filterVars drops invalid names (e.g. a phantom `export PATH`
|
|
359
590
|
// entry) and script-valued vars (e.g. nix's `shellHook`) — they
|
|
360
591
|
// corrupt subprocess environments instead of configuring them.
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
else if (current !== value) outcome.changed++
|
|
366
|
-
process.env[key] = value
|
|
367
|
-
nextApplied.add(key)
|
|
368
|
-
}
|
|
369
|
-
|
|
592
|
+
const counts = reconcileSharedEnv(sharedEnv, process.env, directory, appliedKeys, filteredVars)
|
|
593
|
+
outcome.added += counts.added
|
|
594
|
+
outcome.changed += counts.changed
|
|
595
|
+
outcome.removed += counts.removed
|
|
370
596
|
appliedKeys.clear()
|
|
371
|
-
for (const key of
|
|
372
|
-
|
|
597
|
+
for (const key of counts.nextOwned) appliedKeys.add(key)
|
|
598
|
+
// Inject only the filtered set: the raw payload can carry null
|
|
599
|
+
// unset-signals, and the shell hook writes values verbatim into
|
|
600
|
+
// spawned shell environments (which must be strings).
|
|
601
|
+
currentVars = filterVars(newVars)
|
|
373
602
|
|
|
374
603
|
return outcome
|
|
375
604
|
} catch {
|
|
@@ -487,6 +716,9 @@ export default Plugin.define({
|
|
|
487
716
|
properties: {},
|
|
488
717
|
additionalProperties: false,
|
|
489
718
|
},
|
|
719
|
+
// without this the tool registers as a top-level `reload` instead of
|
|
720
|
+
// joining the `direnv` namespace registered above
|
|
721
|
+
options: { namespace: "direnv" },
|
|
490
722
|
execute: async () => {
|
|
491
723
|
const outcome = await reloadEnv()
|
|
492
724
|
logOutcome(outcome, { initial: false })
|
|
@@ -542,6 +774,9 @@ export default Plugin.define({
|
|
|
542
774
|
return () => {
|
|
543
775
|
controller.abort()
|
|
544
776
|
if (reloadTimer) clearTimeout(reloadTimer)
|
|
777
|
+
// Release our shared-env claims so parallel projects keep their values
|
|
778
|
+
// and fully released keys revert to pre-plugin values.
|
|
779
|
+
releaseAllSharedEnv(sharedEnv, process.env, directory, appliedKeys)
|
|
545
780
|
void shellRegistration.dispose()
|
|
546
781
|
void toolRegistration.dispose()
|
|
547
782
|
}
|