opencode2-direnv 2026.904.1 → 2026.907.1
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/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +155 -23
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
- package/src/index.ts +168 -27
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,30 @@
|
|
|
1
1
|
import { Plugin } from "@opencode-ai/plugin";
|
|
2
|
+
/** fallback PATHs used when repairing a corrupted PATH */
|
|
3
|
+
export declare const sanePath: () => string;
|
|
4
|
+
/** candidate locations for direnv, absolute paths first so that a PATH
|
|
5
|
+
* corruption after setup cannot break the cached resolution */
|
|
6
|
+
export declare const direnvCandidates: () => string[];
|
|
7
|
+
/** Strip known poison from process.env; returns the removed keys. */
|
|
8
|
+
export declare const stripPoison: () => string[];
|
|
9
|
+
/**
|
|
10
|
+
* 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
|
+
* and no script-valued vars (drops nix's `shellHook` and friends).
|
|
13
|
+
*/
|
|
14
|
+
export declare const filterVars: (vars: Record<string, string | null | undefined>) => Record<string, string>;
|
|
15
|
+
/**
|
|
16
|
+
* Repair process.env.PATH if it is corrupted (contains a literal `$`),
|
|
17
|
+
* returning the usable PATH. A corrupted PATH otherwise makes direnv (and
|
|
18
|
+
* every other subprocess this plugin could help) unlaunchable.
|
|
19
|
+
*/
|
|
20
|
+
export declare const repairPath: () => string;
|
|
21
|
+
/**
|
|
22
|
+
* Return the first direnv candidate that responds to `direnv version`, or
|
|
23
|
+
* null. Pure w.r.t. module state so it stays testable.
|
|
24
|
+
*/
|
|
25
|
+
export declare const probeDirenv: (candidates: string[], exec?: (file: string, args: string[]) => Promise<unknown>) => Promise<string | null>;
|
|
26
|
+
/** Find the nearest .envrc at or above `start`, not looking past `stopAt`. */
|
|
27
|
+
export declare const nearestEnvrc: (start: string, stopAt: string | null) => string | null;
|
|
2
28
|
declare const _default: Plugin.Plugin;
|
|
3
29
|
export default _default;
|
|
4
30
|
//# 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;AAmF5C,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;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAQjG,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,QAAO,MAO7B,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;;AA0BD,wBAwQE"}
|
package/dist/index.js
CHANGED
|
@@ -20,12 +20,152 @@ import { promisify } from "node:util";
|
|
|
20
20
|
* *removes* dropped keys so removed variables don't linger
|
|
21
21
|
* - Logs outcomes with a `direnv:` prefix (blocked .envrc is always reported)
|
|
22
22
|
* - Silently skips if direnv is not installed or .envrc is missing
|
|
23
|
+
*
|
|
24
|
+
* Environment hygiene (self-healing):
|
|
25
|
+
*
|
|
26
|
+
* `nix print-dev-env` exports a `shellHook` variable whose value is the raw
|
|
27
|
+
* shell *script* of the devShell hook, typically ending with a line like
|
|
28
|
+
* `export PATH=/nix/store/…:$PATH`. OpenCode 2 parses that text naively and
|
|
29
|
+
* can end up with a bogus env entry literally named `export PATH`, and a PATH
|
|
30
|
+
* value containing a literal `$PATH` breaks every spawned subprocess (local
|
|
31
|
+
* MCP servers die with `MCP error -32000: Connection closed`). Once PATH is
|
|
32
|
+
* corrupted, `execFile("direnv")` fails with ENOENT, so without the repair
|
|
33
|
+
* below the devShell environment can never load again — a permanent breakage
|
|
34
|
+
* loop.
|
|
35
|
+
*
|
|
36
|
+
* Therefore, on every load: strip the poison, repair PATH before invoking
|
|
37
|
+
* direnv, resolve direnv by absolute path as a fallback, and never apply
|
|
38
|
+
* variables that are env-name-invalid or whose value is a shell script.
|
|
23
39
|
*/
|
|
24
40
|
const run = promisify(execFile);
|
|
25
41
|
/** devshell files whose modification should trigger a reload */
|
|
26
42
|
const RELEVANT_FILES = new Set([".envrc", "flake.nix", "flake.lock"]);
|
|
27
43
|
/** debounce window for background reloads (ms) */
|
|
28
44
|
const RELOAD_DEBOUNCE_MS = 1500;
|
|
45
|
+
/** variables whose values are shell scripts, not environment data */
|
|
46
|
+
const SCRIPT_VARS = new Set(["shellHook", "buildPhase", "phases", "prePhases", "postPhases"]);
|
|
47
|
+
/** known-broken env entries to remove from process.env */
|
|
48
|
+
const POISON_VARS = ["shellHook", ...SCRIPT_VARS, "export PATH"];
|
|
49
|
+
/** valid POSIX environment variable names */
|
|
50
|
+
const VALID_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
51
|
+
/** fallback PATHs used when repairing a corrupted PATH */
|
|
52
|
+
export const sanePath = () => {
|
|
53
|
+
const parts = [];
|
|
54
|
+
if (process.env.HOST_PATH)
|
|
55
|
+
parts.push(process.env.HOST_PATH);
|
|
56
|
+
if (process.env.HOME)
|
|
57
|
+
parts.push(`${process.env.HOME}/.nix-profile/bin`);
|
|
58
|
+
if (process.env.USER)
|
|
59
|
+
parts.push(`/etc/profiles/per-user/${process.env.USER}/bin`);
|
|
60
|
+
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");
|
|
61
|
+
return parts.join(":");
|
|
62
|
+
};
|
|
63
|
+
/** candidate locations for direnv, absolute paths first so that a PATH
|
|
64
|
+
* corruption after setup cannot break the cached resolution */
|
|
65
|
+
export const direnvCandidates = () => [
|
|
66
|
+
`/etc/profiles/per-user/${process.env.USER ?? ""}/bin/direnv`,
|
|
67
|
+
`${process.env.HOME ?? ""}/.nix-profile/bin/direnv`,
|
|
68
|
+
"/run/current-system/sw/bin/direnv",
|
|
69
|
+
"/opt/homebrew/bin/direnv",
|
|
70
|
+
"/usr/local/bin/direnv",
|
|
71
|
+
]
|
|
72
|
+
.filter((candidate) => !candidate.includes("//"))
|
|
73
|
+
.concat("direnv");
|
|
74
|
+
/** Strip known poison from process.env; returns the removed keys. */
|
|
75
|
+
export const stripPoison = () => {
|
|
76
|
+
const removed = [];
|
|
77
|
+
for (const key of POISON_VARS) {
|
|
78
|
+
if (key in process.env) {
|
|
79
|
+
delete process.env[key];
|
|
80
|
+
removed.push(key);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return removed;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Filter a `direnv export json` payload down to variables that are safe to
|
|
87
|
+
* apply: valid POSIX names only (drops phantom entries like `export PATH`)
|
|
88
|
+
* and no script-valued vars (drops nix's `shellHook` and friends).
|
|
89
|
+
*/
|
|
90
|
+
export const filterVars = (vars) => {
|
|
91
|
+
const safe = {};
|
|
92
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
93
|
+
if (value == null)
|
|
94
|
+
continue;
|
|
95
|
+
if (!VALID_NAME.test(key) || SCRIPT_VARS.has(key))
|
|
96
|
+
continue;
|
|
97
|
+
safe[key] = value;
|
|
98
|
+
}
|
|
99
|
+
return safe;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Repair process.env.PATH if it is corrupted (contains a literal `$`),
|
|
103
|
+
* returning the usable PATH. A corrupted PATH otherwise makes direnv (and
|
|
104
|
+
* every other subprocess this plugin could help) unlaunchable.
|
|
105
|
+
*/
|
|
106
|
+
export const repairPath = () => {
|
|
107
|
+
const current = process.env.PATH;
|
|
108
|
+
if (current && !current.includes("$"))
|
|
109
|
+
return current;
|
|
110
|
+
const fallback = sanePath();
|
|
111
|
+
process.env.PATH = fallback;
|
|
112
|
+
console.warn(`direnv: repaired corrupted PATH (was ${JSON.stringify(current)})`);
|
|
113
|
+
return fallback;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Return the first direnv candidate that responds to `direnv version`, or
|
|
117
|
+
* null. Pure w.r.t. module state so it stays testable.
|
|
118
|
+
*/
|
|
119
|
+
export const probeDirenv = async (candidates, exec = (file, args) => run(file, args, { encoding: "utf8" })) => {
|
|
120
|
+
for (const candidate of candidates) {
|
|
121
|
+
try {
|
|
122
|
+
await exec(candidate, ["version"]);
|
|
123
|
+
return candidate;
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// try next candidate
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
};
|
|
131
|
+
/** Resolve direnv once; prefers absolute locations, falls back to PATH. */
|
|
132
|
+
let direnvPath;
|
|
133
|
+
const findDirenv = async () => {
|
|
134
|
+
if (direnvPath !== undefined)
|
|
135
|
+
return direnvPath;
|
|
136
|
+
direnvPath = await probeDirenv(direnvCandidates());
|
|
137
|
+
return direnvPath;
|
|
138
|
+
};
|
|
139
|
+
/** Find the nearest .envrc at or above `start`, not looking past `stopAt`. */
|
|
140
|
+
export const nearestEnvrc = (start, stopAt) => {
|
|
141
|
+
let current = start;
|
|
142
|
+
const boundary = stopAt || "/";
|
|
143
|
+
for (;;) {
|
|
144
|
+
const candidate = join(current, ".envrc");
|
|
145
|
+
if (existsSync(candidate))
|
|
146
|
+
return candidate;
|
|
147
|
+
if (current === boundary || current === "/")
|
|
148
|
+
return null;
|
|
149
|
+
const parent = dirname(current);
|
|
150
|
+
if (parent === current)
|
|
151
|
+
return null;
|
|
152
|
+
current = parent;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Strip poison and repair PATH. Runs before every direnv invocation so a
|
|
157
|
+
* daemon that gets corrupted mid-flight heals itself on the next reload.
|
|
158
|
+
* Returns true if anything was repaired.
|
|
159
|
+
*/
|
|
160
|
+
const sanitize = () => {
|
|
161
|
+
const stripped = stripPoison();
|
|
162
|
+
if (stripped.length > 0) {
|
|
163
|
+
console.warn(`direnv: stripped poison vars from process.env: ${stripped.join(", ")}`);
|
|
164
|
+
}
|
|
165
|
+
const before = process.env.PATH;
|
|
166
|
+
repairPath();
|
|
167
|
+
return stripped.length > 0 || process.env.PATH !== before;
|
|
168
|
+
};
|
|
29
169
|
const runText = async (file, args, cwd) => {
|
|
30
170
|
const { stdout } = await run(file, args, {
|
|
31
171
|
cwd,
|
|
@@ -70,24 +210,7 @@ export default Plugin.define({
|
|
|
70
210
|
/**
|
|
71
211
|
* Find .envrc file searching from directory up to stopAt (git root or filesystem root)
|
|
72
212
|
*/
|
|
73
|
-
const findEnvrc = async (startDir, stopAt) =>
|
|
74
|
-
let current = startDir;
|
|
75
|
-
const boundary = stopAt || "/";
|
|
76
|
-
while (true) {
|
|
77
|
-
if (existsSync(join(current, ".envrc"))) {
|
|
78
|
-
return join(current, ".envrc");
|
|
79
|
-
}
|
|
80
|
-
if (current === boundary || current === "/") {
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
const parent = dirname(current);
|
|
84
|
-
if (parent === current) {
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
current = parent;
|
|
88
|
-
}
|
|
89
|
-
return null;
|
|
90
|
-
};
|
|
213
|
+
const findEnvrc = async (startDir, stopAt) => nearestEnvrc(startDir, stopAt);
|
|
91
214
|
/**
|
|
92
215
|
* Resolve (and cache) the directory containing .envrc.
|
|
93
216
|
* Caches only on success; a missing .envrc is re-checked on later triggers
|
|
@@ -101,7 +224,7 @@ export default Plugin.define({
|
|
|
101
224
|
if (envrcPath) {
|
|
102
225
|
envrcDir = dirname(envrcPath);
|
|
103
226
|
}
|
|
104
|
-
discovered =
|
|
227
|
+
discovered = envrcPath !== null;
|
|
105
228
|
return envrcDir;
|
|
106
229
|
};
|
|
107
230
|
const newOutcome = () => ({
|
|
@@ -125,14 +248,22 @@ export default Plugin.define({
|
|
|
125
248
|
return outcome;
|
|
126
249
|
reloading = true;
|
|
127
250
|
try {
|
|
251
|
+
// Self-heal before touching direnv: a corrupted PATH would make the
|
|
252
|
+
// direnv lookup below fail with ENOENT forever.
|
|
253
|
+
sanitize();
|
|
128
254
|
const dir = await resolveEnvrcDir();
|
|
129
255
|
if (!dir) {
|
|
130
256
|
outcome.unavailable = true;
|
|
131
257
|
return outcome;
|
|
132
258
|
}
|
|
259
|
+
const direnv = await findDirenv();
|
|
260
|
+
if (!direnv) {
|
|
261
|
+
outcome.unavailable = true;
|
|
262
|
+
return outcome;
|
|
263
|
+
}
|
|
133
264
|
let jsonText;
|
|
134
265
|
try {
|
|
135
|
-
jsonText = await runText(
|
|
266
|
+
jsonText = await runText(direnv, ["export", "json"], dir);
|
|
136
267
|
}
|
|
137
268
|
catch (error) {
|
|
138
269
|
const stderr = error && typeof error === "object" && "stderr" in error
|
|
@@ -158,10 +289,11 @@ export default Plugin.define({
|
|
|
158
289
|
}
|
|
159
290
|
}
|
|
160
291
|
// 2. Apply current vars, counting additions and value changes.
|
|
292
|
+
// filterVars drops invalid names (e.g. a phantom `export PATH`
|
|
293
|
+
// entry) and script-valued vars (e.g. nix's `shellHook`) — they
|
|
294
|
+
// corrupt subprocess environments instead of configuring them.
|
|
161
295
|
const nextApplied = new Set();
|
|
162
|
-
for (const [key, value] of Object.entries(newVars)) {
|
|
163
|
-
if (value == null)
|
|
164
|
-
continue;
|
|
296
|
+
for (const [key, value] of Object.entries(filterVars(newVars))) {
|
|
165
297
|
const current = process.env[key];
|
|
166
298
|
if (current === undefined)
|
|
167
299
|
outcome.added++;
|
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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode2-direnv",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.0907.1",
|
|
4
4
|
"description": "OpenCode 2 plugin that automatically loads direnv environment variables",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"index.ts"
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build": "tsc"
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"test": "node --import tsx --test \"test/**/*.test.ts\""
|
|
18
19
|
},
|
|
19
20
|
"keywords": [
|
|
20
21
|
"opencode",
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"@opencode-ai/plugin": "^0.0.0-beta-19086",
|
|
43
44
|
"@types/node": "^22.0.0",
|
|
45
|
+
"tsx": "^4.23.13",
|
|
44
46
|
"typescript": "^5.9.3"
|
|
45
47
|
}
|
|
46
48
|
}
|
package/src/index.ts
CHANGED
|
@@ -21,6 +21,22 @@ import { promisify } from "node:util"
|
|
|
21
21
|
* *removes* dropped keys so removed variables don't linger
|
|
22
22
|
* - Logs outcomes with a `direnv:` prefix (blocked .envrc is always reported)
|
|
23
23
|
* - Silently skips if direnv is not installed or .envrc is missing
|
|
24
|
+
*
|
|
25
|
+
* Environment hygiene (self-healing):
|
|
26
|
+
*
|
|
27
|
+
* `nix print-dev-env` exports a `shellHook` variable whose value is the raw
|
|
28
|
+
* shell *script* of the devShell hook, typically ending with a line like
|
|
29
|
+
* `export PATH=/nix/store/…:$PATH`. OpenCode 2 parses that text naively and
|
|
30
|
+
* can end up with a bogus env entry literally named `export PATH`, and a PATH
|
|
31
|
+
* value containing a literal `$PATH` breaks every spawned subprocess (local
|
|
32
|
+
* MCP servers die with `MCP error -32000: Connection closed`). Once PATH is
|
|
33
|
+
* corrupted, `execFile("direnv")` fails with ENOENT, so without the repair
|
|
34
|
+
* below the devShell environment can never load again — a permanent breakage
|
|
35
|
+
* loop.
|
|
36
|
+
*
|
|
37
|
+
* Therefore, on every load: strip the poison, repair PATH before invoking
|
|
38
|
+
* direnv, resolve direnv by absolute path as a fallback, and never apply
|
|
39
|
+
* variables that are env-name-invalid or whose value is a shell script.
|
|
24
40
|
*/
|
|
25
41
|
|
|
26
42
|
const run = promisify(execFile)
|
|
@@ -56,6 +72,141 @@ const RELEVANT_FILES = new Set([".envrc", "flake.nix", "flake.lock"])
|
|
|
56
72
|
/** debounce window for background reloads (ms) */
|
|
57
73
|
const RELOAD_DEBOUNCE_MS = 1500
|
|
58
74
|
|
|
75
|
+
/** variables whose values are shell scripts, not environment data */
|
|
76
|
+
const SCRIPT_VARS = new Set(["shellHook", "buildPhase", "phases", "prePhases", "postPhases"])
|
|
77
|
+
|
|
78
|
+
/** known-broken env entries to remove from process.env */
|
|
79
|
+
const POISON_VARS = ["shellHook", ...SCRIPT_VARS, "export PATH"]
|
|
80
|
+
|
|
81
|
+
/** valid POSIX environment variable names */
|
|
82
|
+
const VALID_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/
|
|
83
|
+
|
|
84
|
+
/** fallback PATHs used when repairing a corrupted PATH */
|
|
85
|
+
export const sanePath = () => {
|
|
86
|
+
const parts: string[] = []
|
|
87
|
+
if (process.env.HOST_PATH) parts.push(process.env.HOST_PATH)
|
|
88
|
+
if (process.env.HOME) parts.push(`${process.env.HOME}/.nix-profile/bin`)
|
|
89
|
+
if (process.env.USER) parts.push(`/etc/profiles/per-user/${process.env.USER}/bin`)
|
|
90
|
+
parts.push(
|
|
91
|
+
"/nix/var/nix/profiles/default/bin",
|
|
92
|
+
"/run/current-system/sw/bin",
|
|
93
|
+
"/opt/homebrew/bin",
|
|
94
|
+
"/usr/local/bin",
|
|
95
|
+
"/usr/bin:/bin:/usr/sbin:/sbin",
|
|
96
|
+
)
|
|
97
|
+
return parts.join(":")
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** candidate locations for direnv, absolute paths first so that a PATH
|
|
101
|
+
* corruption after setup cannot break the cached resolution */
|
|
102
|
+
export const direnvCandidates = () =>
|
|
103
|
+
[
|
|
104
|
+
`/etc/profiles/per-user/${process.env.USER ?? ""}/bin/direnv`,
|
|
105
|
+
`${process.env.HOME ?? ""}/.nix-profile/bin/direnv`,
|
|
106
|
+
"/run/current-system/sw/bin/direnv",
|
|
107
|
+
"/opt/homebrew/bin/direnv",
|
|
108
|
+
"/usr/local/bin/direnv",
|
|
109
|
+
]
|
|
110
|
+
.filter((candidate) => !candidate.includes("//"))
|
|
111
|
+
.concat("direnv")
|
|
112
|
+
|
|
113
|
+
/** Strip known poison from process.env; returns the removed keys. */
|
|
114
|
+
export const stripPoison = (): string[] => {
|
|
115
|
+
const removed: string[] = []
|
|
116
|
+
for (const key of POISON_VARS) {
|
|
117
|
+
if (key in process.env) {
|
|
118
|
+
delete process.env[key]
|
|
119
|
+
removed.push(key)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return removed
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Filter a `direnv export json` payload down to variables that are safe to
|
|
127
|
+
* apply: valid POSIX names only (drops phantom entries like `export PATH`)
|
|
128
|
+
* and no script-valued vars (drops nix's `shellHook` and friends).
|
|
129
|
+
*/
|
|
130
|
+
export const filterVars = (vars: Record<string, string | null | undefined>): Record<string, string> => {
|
|
131
|
+
const safe: Record<string, string> = {}
|
|
132
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
133
|
+
if (value == null) continue
|
|
134
|
+
if (!VALID_NAME.test(key) || SCRIPT_VARS.has(key)) continue
|
|
135
|
+
safe[key] = value
|
|
136
|
+
}
|
|
137
|
+
return safe
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Repair process.env.PATH if it is corrupted (contains a literal `$`),
|
|
142
|
+
* returning the usable PATH. A corrupted PATH otherwise makes direnv (and
|
|
143
|
+
* every other subprocess this plugin could help) unlaunchable.
|
|
144
|
+
*/
|
|
145
|
+
export const repairPath = (): string => {
|
|
146
|
+
const current = process.env.PATH
|
|
147
|
+
if (current && !current.includes("$")) return current
|
|
148
|
+
const fallback = sanePath()
|
|
149
|
+
process.env.PATH = fallback
|
|
150
|
+
console.warn(`direnv: repaired corrupted PATH (was ${JSON.stringify(current)})`)
|
|
151
|
+
return fallback
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Return the first direnv candidate that responds to `direnv version`, or
|
|
156
|
+
* null. Pure w.r.t. module state so it stays testable.
|
|
157
|
+
*/
|
|
158
|
+
export const probeDirenv = async (
|
|
159
|
+
candidates: string[],
|
|
160
|
+
exec: (file: string, args: string[]) => Promise<unknown> = (file, args) => run(file, args, { encoding: "utf8" })
|
|
161
|
+
): Promise<string | null> => {
|
|
162
|
+
for (const candidate of candidates) {
|
|
163
|
+
try {
|
|
164
|
+
await exec(candidate, ["version"])
|
|
165
|
+
return candidate
|
|
166
|
+
} catch {
|
|
167
|
+
// try next candidate
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return null
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** Resolve direnv once; prefers absolute locations, falls back to PATH. */
|
|
174
|
+
let direnvPath: string | null | undefined
|
|
175
|
+
const findDirenv = async (): Promise<string | null> => {
|
|
176
|
+
if (direnvPath !== undefined) return direnvPath
|
|
177
|
+
direnvPath = await probeDirenv(direnvCandidates())
|
|
178
|
+
return direnvPath
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** Find the nearest .envrc at or above `start`, not looking past `stopAt`. */
|
|
182
|
+
export const nearestEnvrc = (start: string, stopAt: string | null): string | null => {
|
|
183
|
+
let current = start
|
|
184
|
+
const boundary = stopAt || "/"
|
|
185
|
+
for (;;) {
|
|
186
|
+
const candidate = join(current, ".envrc")
|
|
187
|
+
if (existsSync(candidate)) return candidate
|
|
188
|
+
if (current === boundary || current === "/") return null
|
|
189
|
+
const parent = dirname(current)
|
|
190
|
+
if (parent === current) return null
|
|
191
|
+
current = parent
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Strip poison and repair PATH. Runs before every direnv invocation so a
|
|
197
|
+
* daemon that gets corrupted mid-flight heals itself on the next reload.
|
|
198
|
+
* Returns true if anything was repaired.
|
|
199
|
+
*/
|
|
200
|
+
const sanitize = (): boolean => {
|
|
201
|
+
const stripped = stripPoison()
|
|
202
|
+
if (stripped.length > 0) {
|
|
203
|
+
console.warn(`direnv: stripped poison vars from process.env: ${stripped.join(", ")}`)
|
|
204
|
+
}
|
|
205
|
+
const before = process.env.PATH
|
|
206
|
+
repairPath()
|
|
207
|
+
return stripped.length > 0 || process.env.PATH !== before
|
|
208
|
+
}
|
|
209
|
+
|
|
59
210
|
const runText = async (file: string, args: string[], cwd: string) => {
|
|
60
211
|
const { stdout } = await run(file, args, {
|
|
61
212
|
cwd,
|
|
@@ -112,29 +263,7 @@ export default Plugin.define({
|
|
|
112
263
|
const findEnvrc = async (
|
|
113
264
|
startDir: string,
|
|
114
265
|
stopAt: string | null
|
|
115
|
-
): Promise<string | null> =>
|
|
116
|
-
let current = startDir
|
|
117
|
-
const boundary = stopAt || "/"
|
|
118
|
-
|
|
119
|
-
while (true) {
|
|
120
|
-
if (existsSync(join(current, ".envrc"))) {
|
|
121
|
-
return join(current, ".envrc")
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (current === boundary || current === "/") {
|
|
125
|
-
break
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const parent = dirname(current)
|
|
129
|
-
if (parent === current) {
|
|
130
|
-
break
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
current = parent
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return null
|
|
137
|
-
}
|
|
266
|
+
): Promise<string | null> => nearestEnvrc(startDir, stopAt)
|
|
138
267
|
|
|
139
268
|
/**
|
|
140
269
|
* Resolve (and cache) the directory containing .envrc.
|
|
@@ -148,7 +277,7 @@ export default Plugin.define({
|
|
|
148
277
|
if (envrcPath) {
|
|
149
278
|
envrcDir = dirname(envrcPath)
|
|
150
279
|
}
|
|
151
|
-
discovered =
|
|
280
|
+
discovered = envrcPath !== null
|
|
152
281
|
return envrcDir
|
|
153
282
|
}
|
|
154
283
|
|
|
@@ -174,15 +303,25 @@ export default Plugin.define({
|
|
|
174
303
|
reloading = true
|
|
175
304
|
|
|
176
305
|
try {
|
|
306
|
+
// Self-heal before touching direnv: a corrupted PATH would make the
|
|
307
|
+
// direnv lookup below fail with ENOENT forever.
|
|
308
|
+
sanitize()
|
|
309
|
+
|
|
177
310
|
const dir = await resolveEnvrcDir()
|
|
178
311
|
if (!dir) {
|
|
179
312
|
outcome.unavailable = true
|
|
180
313
|
return outcome
|
|
181
314
|
}
|
|
182
315
|
|
|
316
|
+
const direnv = await findDirenv()
|
|
317
|
+
if (!direnv) {
|
|
318
|
+
outcome.unavailable = true
|
|
319
|
+
return outcome
|
|
320
|
+
}
|
|
321
|
+
|
|
183
322
|
let jsonText: string
|
|
184
323
|
try {
|
|
185
|
-
jsonText = await runText(
|
|
324
|
+
jsonText = await runText(direnv, ["export", "json"], dir)
|
|
186
325
|
} catch (error: unknown) {
|
|
187
326
|
const stderr =
|
|
188
327
|
error && typeof error === "object" && "stderr" in error
|
|
@@ -211,9 +350,11 @@ export default Plugin.define({
|
|
|
211
350
|
}
|
|
212
351
|
|
|
213
352
|
// 2. Apply current vars, counting additions and value changes.
|
|
353
|
+
// filterVars drops invalid names (e.g. a phantom `export PATH`
|
|
354
|
+
// entry) and script-valued vars (e.g. nix's `shellHook`) — they
|
|
355
|
+
// corrupt subprocess environments instead of configuring them.
|
|
214
356
|
const nextApplied = new Set<string>()
|
|
215
|
-
for (const [key, value] of Object.entries(newVars)) {
|
|
216
|
-
if (value == null) continue
|
|
357
|
+
for (const [key, value] of Object.entries(filterVars(newVars))) {
|
|
217
358
|
const current = process.env[key]
|
|
218
359
|
if (current === undefined) outcome.added++
|
|
219
360
|
else if (current !== value) outcome.changed++
|