opencode2-direnv 2026.907.0 → 2026.908.0

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 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
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;;AAmL5C,wBAgSE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAwF5C,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,wBAqUE"}
package/dist/index.js CHANGED
@@ -14,6 +14,11 @@ import { promisify } from "node:util";
14
14
  * - On plugin setup: load env once (awaited, so the first command is ready)
15
15
  * - On session.created: re-sync per new session (e.g. after `direnv allow`)
16
16
  * - On filesystem.changed for .envrc/flake.nix/flake.lock: debounced reload
17
+ * (NOTE: as of server beta-19151 the server declares but never emits
18
+ * filesystem.changed, so this trigger is dormant; use the direnv_reload
19
+ * tool until an fs watcher or server-side emission exists)
20
+ * - Exposes a `direnv_reload` tool so the agent can force a re-sync manually
21
+ * (e.g. after the user edits the flake in their own editor/terminal)
17
22
  * - Injects the latest direnv export into every spawned shell via the
18
23
  * `shell.create.before` hook (primary mechanism)
19
24
  * - Reconciles process.env as a fallback for other subprocesses (LSP, MCP) and
@@ -49,7 +54,7 @@ const POISON_VARS = ["shellHook", ...SCRIPT_VARS, "export PATH"];
49
54
  /** valid POSIX environment variable names */
50
55
  const VALID_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
51
56
  /** fallback PATHs used when repairing a corrupted PATH */
52
- const sanePath = () => {
57
+ export const sanePath = () => {
53
58
  const parts = [];
54
59
  if (process.env.HOST_PATH)
55
60
  parts.push(process.env.HOST_PATH);
@@ -62,7 +67,7 @@ const sanePath = () => {
62
67
  };
63
68
  /** candidate locations for direnv, absolute paths first so that a PATH
64
69
  * corruption after setup cannot break the cached resolution */
65
- const direnvCandidates = () => [
70
+ export const direnvCandidates = () => [
66
71
  `/etc/profiles/per-user/${process.env.USER ?? ""}/bin/direnv`,
67
72
  `${process.env.HOME ?? ""}/.nix-profile/bin/direnv`,
68
73
  "/run/current-system/sw/bin/direnv",
@@ -72,7 +77,7 @@ const direnvCandidates = () => [
72
77
  .filter((candidate) => !candidate.includes("//"))
73
78
  .concat("direnv");
74
79
  /** Strip known poison from process.env; returns the removed keys. */
75
- const stripPoison = () => {
80
+ export const stripPoison = () => {
76
81
  const removed = [];
77
82
  for (const key of POISON_VARS) {
78
83
  if (key in process.env) {
@@ -82,12 +87,28 @@ const stripPoison = () => {
82
87
  }
83
88
  return removed;
84
89
  };
90
+ /**
91
+ * 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
+ * and no script-valued vars (drops nix's `shellHook` and friends).
94
+ */
95
+ export const filterVars = (vars) => {
96
+ const safe = {};
97
+ for (const [key, value] of Object.entries(vars)) {
98
+ if (value == null)
99
+ continue;
100
+ if (!VALID_NAME.test(key) || SCRIPT_VARS.has(key))
101
+ continue;
102
+ safe[key] = value;
103
+ }
104
+ return safe;
105
+ };
85
106
  /**
86
107
  * Repair process.env.PATH if it is corrupted (contains a literal `$`),
87
108
  * returning the usable PATH. A corrupted PATH otherwise makes direnv (and
88
109
  * every other subprocess this plugin could help) unlaunchable.
89
110
  */
90
- const repairPath = () => {
111
+ export const repairPath = () => {
91
112
  const current = process.env.PATH;
92
113
  if (current && !current.includes("$"))
93
114
  return current;
@@ -96,24 +117,46 @@ const repairPath = () => {
96
117
  console.warn(`direnv: repaired corrupted PATH (was ${JSON.stringify(current)})`);
97
118
  return fallback;
98
119
  };
99
- /** Resolve direnv once; prefers absolute locations, falls back to PATH. */
100
- let direnvPath;
101
- const findDirenv = async () => {
102
- if (direnvPath !== undefined)
103
- return direnvPath;
104
- for (const candidate of direnvCandidates()) {
120
+ /**
121
+ * Return the first direnv candidate that responds to `direnv version`, or
122
+ * null. Pure w.r.t. module state so it stays testable.
123
+ */
124
+ export const probeDirenv = async (candidates, exec = (file, args) => run(file, args, { encoding: "utf8" })) => {
125
+ for (const candidate of candidates) {
105
126
  try {
106
- await run(candidate, ["version"], { encoding: "utf8" });
107
- direnvPath = candidate;
108
- return direnvPath;
127
+ await exec(candidate, ["version"]);
128
+ return candidate;
109
129
  }
110
130
  catch {
111
131
  // try next candidate
112
132
  }
113
133
  }
114
- direnvPath = null;
134
+ return null;
135
+ };
136
+ /** Resolve direnv once; prefers absolute locations, falls back to PATH. */
137
+ let direnvPath;
138
+ const findDirenv = async () => {
139
+ if (direnvPath !== undefined)
140
+ return direnvPath;
141
+ direnvPath = await probeDirenv(direnvCandidates());
115
142
  return direnvPath;
116
143
  };
144
+ /** Find the nearest .envrc at or above `start`, not looking past `stopAt`. */
145
+ export const nearestEnvrc = (start, stopAt) => {
146
+ let current = start;
147
+ const boundary = stopAt || "/";
148
+ for (;;) {
149
+ const candidate = join(current, ".envrc");
150
+ if (existsSync(candidate))
151
+ return candidate;
152
+ if (current === boundary || current === "/")
153
+ return null;
154
+ const parent = dirname(current);
155
+ if (parent === current)
156
+ return null;
157
+ current = parent;
158
+ }
159
+ };
117
160
  /**
118
161
  * Strip poison and repair PATH. Runs before every direnv invocation so a
119
162
  * daemon that gets corrupted mid-flight heals itself on the next reload.
@@ -172,24 +215,7 @@ export default Plugin.define({
172
215
  /**
173
216
  * Find .envrc file searching from directory up to stopAt (git root or filesystem root)
174
217
  */
175
- const findEnvrc = async (startDir, stopAt) => {
176
- let current = startDir;
177
- const boundary = stopAt || "/";
178
- while (true) {
179
- if (existsSync(join(current, ".envrc"))) {
180
- return join(current, ".envrc");
181
- }
182
- if (current === boundary || current === "/") {
183
- break;
184
- }
185
- const parent = dirname(current);
186
- if (parent === current) {
187
- break;
188
- }
189
- current = parent;
190
- }
191
- return null;
192
- };
218
+ const findEnvrc = async (startDir, stopAt) => nearestEnvrc(startDir, stopAt);
193
219
  /**
194
220
  * Resolve (and cache) the directory containing .envrc.
195
221
  * Caches only on success; a missing .envrc is re-checked on later triggers
@@ -268,15 +294,11 @@ export default Plugin.define({
268
294
  }
269
295
  }
270
296
  // 2. Apply current vars, counting additions and value changes.
271
- // Skip invalid names (e.g. a phantom `export PATH` entry) and
272
- // script-valued vars (e.g. nix's `shellHook`) — they corrupt
273
- // subprocess environments instead of configuring them.
297
+ // filterVars drops invalid names (e.g. a phantom `export PATH`
298
+ // entry) and script-valued vars (e.g. nix's `shellHook`) — they
299
+ // corrupt subprocess environments instead of configuring them.
274
300
  const nextApplied = new Set();
275
- for (const [key, value] of Object.entries(newVars)) {
276
- if (value == null)
277
- continue;
278
- if (!VALID_NAME.test(key) || SCRIPT_VARS.has(key))
279
- continue;
301
+ for (const [key, value] of Object.entries(filterVars(newVars))) {
280
302
  const current = process.env[key];
281
303
  if (current === undefined)
282
304
  outcome.added++;
@@ -347,6 +369,31 @@ export default Plugin.define({
347
369
  };
348
370
  // Initial load: awaited so the first command of any session sees the env.
349
371
  logOutcome(await reloadEnv(), { initial: true });
372
+ /**
373
+ * Human/agent-readable one-liner for a reload outcome, used by the
374
+ * direnv_reload tool result.
375
+ */
376
+ const describeOutcome = (outcome) => {
377
+ if (outcome.blocked) {
378
+ return "direnv: .envrc is blocked. Run `direnv allow` and retry.";
379
+ }
380
+ if (outcome.unavailable) {
381
+ return "direnv: unavailable (direnv not installed or no .envrc found).";
382
+ }
383
+ if (outcome.error) {
384
+ return "direnv: `direnv export json` failed; see server logs for details.";
385
+ }
386
+ const parts = [];
387
+ if (outcome.added)
388
+ parts.push(`+${outcome.added}`);
389
+ if (outcome.changed)
390
+ parts.push(`~${outcome.changed}`);
391
+ if (outcome.removed)
392
+ parts.push(`-${outcome.removed}`);
393
+ return parts.length
394
+ ? `direnv: reloaded (${parts.join(" ")}); new shells use the updated environment.`
395
+ : "direnv: reloaded, nothing changed.";
396
+ };
350
397
  // Primary mechanism: inject the latest direnv export into every shell the
351
398
  // server spawns for a working copy inside the devshell. The cached payload
352
399
  // keeps the hook synchronous and non-blocking.
@@ -359,6 +406,36 @@ export default Plugin.define({
359
406
  event.env[key] = value;
360
407
  }
361
408
  });
409
+ /**
410
+ * Agent-facing manual reload. The filesystem.changed event the background
411
+ * reload depends on is declared but not emitted by current OpenCode 2
412
+ * servers, so after the user edits .envrc/flake.nix in their own editor
413
+ * the environment would silently go stale. This tool lets the agent force
414
+ * a re-sync on demand (works regardless of server-side event support).
415
+ */
416
+ const toolRegistration = await ctx.tool.transform((editor) => {
417
+ editor.namespace({
418
+ name: "direnv",
419
+ description: "Devshell (direnv) environment tools",
420
+ });
421
+ editor.add({
422
+ name: "reload",
423
+ description: "Re-export the direnv devshell and apply it to OpenCode, so subsequently spawned shells " +
424
+ "see the updated environment. Call this after .envrc, flake.nix, or flake.lock were changed " +
425
+ "outside OpenCode (user edited them mid-session), or when devshell-provided tools are missing " +
426
+ "from PATH / resolve to stale /nix/store paths.",
427
+ input: {
428
+ type: "object",
429
+ properties: {},
430
+ additionalProperties: false,
431
+ },
432
+ execute: async () => {
433
+ const outcome = await reloadEnv();
434
+ logOutcome(outcome, { initial: false });
435
+ return { content: describeOutcome(outcome) };
436
+ },
437
+ });
438
+ });
362
439
  const isRelevantLocation = (location) => !location?.directory || location.directory === directory;
363
440
  // Event stream: per-session sync and devshell-file watch. Runs detached so
364
441
  // plugin setup is never blocked; aborted on cleanup.
@@ -393,8 +470,14 @@ export default Plugin.define({
393
470
  }
394
471
  }
395
472
  }
396
- catch {
397
- // stream aborted on cleanup or failed; nothing to do
473
+ catch (error) {
474
+ // Abort is the normal cleanup path (controller aborted in teardown);
475
+ // anything else means we silently lost session.created/filesystem.changed
476
+ // triggers and the environment will go stale without anyone knowing.
477
+ if (controller.signal.aborted)
478
+ return;
479
+ const detail = error instanceof Error ? `${error.message}` : String(error);
480
+ console.warn(`direnv: event stream failed, devshell reload triggers are dead: ${detail}`);
398
481
  }
399
482
  })();
400
483
  return () => {
@@ -402,6 +485,7 @@ export default Plugin.define({
402
485
  if (reloadTimer)
403
486
  clearTimeout(reloadTimer);
404
487
  void shellRegistration.dispose();
488
+ void toolRegistration.dispose();
405
489
  };
406
490
  },
407
491
  });
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":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AA2B/B,gEAAgE;AAChE,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAA;AAErE,kDAAkD;AAClD,MAAM,kBAAkB,GAAG,IAAI,CAAA;AAE/B,qEAAqE;AACrE,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAA;AAE7F,0DAA0D;AAC1D,MAAM,WAAW,GAAG,CAAC,WAAW,EAAE,GAAG,WAAW,EAAE,aAAa,CAAC,CAAA;AAEhE,6CAA6C;AAC7C,MAAM,UAAU,GAAG,0BAA0B,CAAA;AAE7C,0DAA0D;AAC1D,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,EAAE;IAC3B,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAC5D,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,mBAAmB,CAAC,CAAA;IACxE,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,0BAA0B,OAAO,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,CAAA;IAClF,KAAK,CAAC,IAAI,CACR,mCAAmC,EACnC,4BAA4B,EAC5B,mBAAmB,EACnB,gBAAgB,EAChB,+BAA+B,CAChC,CAAA;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACxB,CAAC,CAAA;AAED;+DAC+D;AAC/D,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE,CACnC;IACE,0BAA0B,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,aAAa;IAC7D,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,0BAA0B;IACnD,mCAAmC;IACnC,0BAA0B;IAC1B,uBAAuB;CACxB;KACE,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;KAChD,MAAM,CAAC,QAAQ,CAAC,CAAA;AAErB,qEAAqE;AACrE,MAAM,CAAC,MAAM,WAAW,GAAG,GAAa,EAAE;IACxC,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,IAAI,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YACvB,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACvB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACnB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAA+C,EAA0B,EAAE;IACpG,MAAM,IAAI,GAA2B,EAAE,CAAA;IACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,KAAK,IAAI,IAAI;YAAE,SAAQ;QAC3B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAQ;QAC3D,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;IACnB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,GAAW,EAAE;IACrC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAA;IAChC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,OAAO,CAAA;IACrD,MAAM,QAAQ,GAAG,QAAQ,EAAE,CAAA;IAC3B,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,QAAQ,CAAA;IAC3B,OAAO,CAAC,IAAI,CAAC,wCAAwC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAChF,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAC9B,UAAoB,EACpB,OAA2D,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EACxF,EAAE;IAC1B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;YAClC,OAAO,SAAS,CAAA;QAClB,CAAC;QAAC,MAAM,CAAC;YACP,qBAAqB;QACvB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,2EAA2E;AAC3E,IAAI,UAAqC,CAAA;AACzC,MAAM,UAAU,GAAG,KAAK,IAA4B,EAAE;IACpD,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,UAAU,CAAA;IAC/C,UAAU,GAAG,MAAM,WAAW,CAAC,gBAAgB,EAAE,CAAC,CAAA;IAClD,OAAO,UAAU,CAAA;AACnB,CAAC,CAAA;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,MAAqB,EAAiB,EAAE;IAClF,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,MAAM,QAAQ,GAAG,MAAM,IAAI,GAAG,CAAA;IAC9B,SAAS,CAAC;QACR,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QACzC,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAA;QAC3C,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,GAAG;YAAE,OAAO,IAAI,CAAA;QACxD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;QAC/B,IAAI,MAAM,KAAK,OAAO;YAAE,OAAO,IAAI,CAAA;QACnC,OAAO,GAAG,MAAM,CAAA;IAClB,CAAC;AACH,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,QAAQ,GAAG,GAAY,EAAE;IAC7B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,IAAI,CAAC,kDAAkD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACvF,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAA;IAC/B,UAAU,EAAE,CAAA;IACZ,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,CAAA;AAC3D,CAAC,CAAA;AAED,MAAM,OAAO,GAAG,KAAK,EAAE,IAAY,EAAE,IAAc,EAAE,GAAW,EAAE,EAAE;IAClE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE;QACvC,GAAG;QACH,QAAQ,EAAE,MAAM;QAChB,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;KAC5B,CAAC,CAAA;IACF,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,eAAe,MAAM,CAAC,MAAM,CAAC;IAC3B,EAAE,EAAE,kBAAkB;IAEtB,KAAK,CAAC,KAAK,CAAC,GAAG;QACb,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAA;QAExC;;;WAGG;QACH,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAA;QAExC;;;;WAIG;QACH,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;QAErC,mFAAmF;QACnF,IAAI,WAAW,GAA2B,EAAE,CAAA;QAE5C,mEAAmE;QACnE,IAAI,QAAQ,GAAkB,IAAI,CAAA;QAClC,IAAI,UAAU,GAAG,KAAK,CAAA;QAEtB,4DAA4D;QAC5D,IAAI,SAAS,GAAG,KAAK,CAAA;QAErB,IAAI,WAAW,GAAyC,IAAI,CAAA;QAC5D,IAAI,iBAAiB,GAAG,KAAK,CAAA;QAE7B,MAAM,WAAW,GAAG,KAAK,IAA4B,EAAE;YACrD,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,SAAS,CAAC,CAAA;gBAChF,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,CAAA;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAA;YACb,CAAC;QACH,CAAC,CAAA;QAED;;WAEG;QACH,MAAM,SAAS,GAAG,KAAK,EACrB,QAAgB,EAChB,MAAqB,EACG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QAE3D;;;;WAIG;QACH,MAAM,eAAe,GAAG,KAAK,IAA4B,EAAE;YACzD,IAAI,UAAU;gBAAE,OAAO,QAAQ,CAAA;YAC/B,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAA;YACnC,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;YACrD,IAAI,SAAS,EAAE,CAAC;gBACd,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;YAC/B,CAAC;YACD,UAAU,GAAG,SAAS,KAAK,IAAI,CAAA;YAC/B,OAAO,QAAQ,CAAA;QACjB,CAAC,CAAA;QAED,MAAM,UAAU,GAAG,GAAkB,EAAE,CAAC,CAAC;YACvC,OAAO,EAAE,KAAK;YACd,WAAW,EAAE,KAAK;YAClB,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,CAAC;SACX,CAAC,CAAA;QAEF;;;;;;WAMG;QACH,MAAM,SAAS,GAAG,KAAK,IAA4B,EAAE;YACnD,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;YAC5B,IAAI,SAAS;gBAAE,OAAO,OAAO,CAAA;YAC7B,SAAS,GAAG,IAAI,CAAA;YAEhB,IAAI,CAAC;gBACH,oEAAoE;gBACpE,gDAAgD;gBAChD,QAAQ,EAAE,CAAA;gBAEV,MAAM,GAAG,GAAG,MAAM,eAAe,EAAE,CAAA;gBACnC,IAAI,CAAC,GAAG,EAAE,CAAC;oBACT,OAAO,CAAC,WAAW,GAAG,IAAI,CAAA;oBAC1B,OAAO,OAAO,CAAA;gBAChB,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAA;gBACjC,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,OAAO,CAAC,WAAW,GAAG,IAAI,CAAA;oBAC1B,OAAO,OAAO,CAAA;gBAChB,CAAC;gBAED,IAAI,QAAgB,CAAA;gBACpB,IAAI,CAAC;oBACH,QAAQ,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,CAAA;gBAC3D,CAAC;gBAAC,OAAO,KAAc,EAAE,CAAC;oBACxB,MAAM,MAAM,GACV,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,IAAI,KAAK;wBACrD,CAAC,CAAC,MAAM,CAAE,KAA6B,CAAC,MAAM,IAAI,EAAE,CAAC;wBACrD,CAAC,CAAC,EAAE,CAAA;oBACR,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;wBAClC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAA;oBACxB,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,KAAK,GAAG,IAAI,CAAA;oBACtB,CAAC;oBACD,OAAO,OAAO,CAAA;gBAChB,CAAC;gBAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;gBAC1D,MAAM,OAAO,GACX,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;gBAEpD,4EAA4E;gBAC5E,mEAAmE;gBACnE,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;oBAC9B,MAAM,IAAI,GAAG,GAAG,IAAI,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAA;oBACnD,IAAI,CAAC,IAAI,IAAI,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;wBAChC,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;wBACvB,OAAO,CAAC,OAAO,EAAE,CAAA;oBACnB,CAAC;gBACH,CAAC;gBAED,+DAA+D;gBAC/D,kEAAkE;gBAClE,mEAAmE;gBACnE,kEAAkE;gBAClE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;gBACrC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;oBAC/D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;oBAChC,IAAI,OAAO,KAAK,SAAS;wBAAE,OAAO,CAAC,KAAK,EAAE,CAAA;yBACrC,IAAI,OAAO,KAAK,KAAK;wBAAE,OAAO,CAAC,OAAO,EAAE,CAAA;oBAC7C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;oBACxB,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;gBACtB,CAAC;gBAED,WAAW,CAAC,KAAK,EAAE,CAAA;gBACnB,KAAK,MAAM,GAAG,IAAI,WAAW;oBAAE,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;gBACnD,WAAW,GAAG,OAAO,CAAA;gBAErB,OAAO,OAAO,CAAA;YAChB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,KAAK,GAAG,IAAI,CAAA;gBACpB,OAAO,OAAO,CAAA;YAChB,CAAC;oBAAS,CAAC;gBACT,SAAS,GAAG,KAAK,CAAA;YACnB,CAAC;QACH,CAAC,CAAA;QAED;;;;;;;WAOG;QACH,MAAM,UAAU,GAAG,CAAC,OAAsB,EAAE,IAA0B,EAAE,EAAE;YACxE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAO,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAA;gBACxE,OAAM;YACR,CAAC;YACD,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,KAAK;gBAAE,OAAM;YAEhD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;YAE/D,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACvC,iBAAiB,GAAG,IAAI,CAAA;gBACxB,IAAI,KAAK,GAAG,CAAC,IAAI,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;oBACtC,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAA;gBAC3C,CAAC;gBACD,OAAM;YACR,CAAC;YAED,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACd,MAAM,KAAK,GAAa,EAAE,CAAA;gBAC1B,IAAI,OAAO,CAAC,KAAK;oBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA;gBAClD,IAAI,OAAO,CAAC,OAAO;oBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;gBACtD,IAAI,OAAO,CAAC,OAAO;oBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;gBACtD,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACtD,CAAC;QACH,CAAC,CAAA;QAED;;;WAGG;QACH,MAAM,cAAc,GAAG,CAAC,OAAe,EAAE,EAAE;YACzC,IAAI,WAAW;gBAAE,YAAY,CAAC,WAAW,CAAC,CAAA;YAC1C,WAAW,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,WAAW,GAAG,IAAI,CAAA;gBAClB,KAAK,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;YAC7E,CAAC,EAAE,OAAO,CAAC,CAAA;QACb,CAAC,CAAA;QAED,0EAA0E;QAC1E,UAAU,CAAC,MAAM,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;QAEhD;;;WAGG;QACH,MAAM,eAAe,GAAG,CAAC,OAAsB,EAAU,EAAE;YACzD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAO,0DAA0D,CAAA;YACnE,CAAC;YACD,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;gBACxB,OAAO,gEAAgE,CAAA;YACzE,CAAC;YACD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBAClB,OAAO,mEAAmE,CAAA;YAC5E,CAAC;YACD,MAAM,KAAK,GAAa,EAAE,CAAA;YAC1B,IAAI,OAAO,CAAC,KAAK;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA;YAClD,IAAI,OAAO,CAAC,OAAO;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;YACtD,IAAI,OAAO,CAAC,OAAO;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;YACtD,OAAO,KAAK,CAAC,MAAM;gBACjB,CAAC,CAAC,qBAAqB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,4CAA4C;gBAClF,CAAC,CAAC,oCAAoC,CAAA;QAC1C,CAAC,CAAA;QAED,0EAA0E;QAC1E,2EAA2E;QAC3E,+CAA+C;QAC/C,MAAM,iBAAiB,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;YACxE,IAAI,CAAC,QAAQ;gBAAE,OAAM;YACrB,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC;gBAAE,OAAM;YAC3E,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;gBACvD,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;YACxB,CAAC;QACH,CAAC,CAAC,CAAA;QAEF;;;;;;WAMG;QACH,MAAM,gBAAgB,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE;YAC3D,MAAM,CAAC,SAAS,CAAC;gBACf,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,qCAAqC;aACnD,CAAC,CAAA;YACF,MAAM,CAAC,GAAG,CAAC;gBACT,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,yFAAyF;oBACzF,6FAA6F;oBAC7F,+FAA+F;oBAC/F,gDAAgD;gBAClD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE,EAAE;oBACd,oBAAoB,EAAE,KAAK;iBAC5B;gBACD,OAAO,EAAE,KAAK,IAAI,EAAE;oBAClB,MAAM,OAAO,GAAG,MAAM,SAAS,EAAE,CAAA;oBACjC,UAAU,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;oBACvC,OAAO,EAAE,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,CAAA;gBAC9C,CAAC;aACF,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QAEF,MAAM,kBAAkB,GAAG,CAAC,QAAkC,EAAE,EAAE,CAChE,CAAC,QAAQ,EAAE,SAAS,IAAI,QAAQ,CAAC,SAAS,KAAK,SAAS,CAAA;QAE1D,2EAA2E;QAC3E,qDAAqD;QACrD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;QACxC,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,CAAC;gBACH,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;oBAC3E,MAAM,KAAK,GAAG,GAA8B,CAAA;oBAE5C,kEAAkE;oBAClE,2CAA2C;oBAC3C,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;wBACrC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAsC,CAAA;wBACzD,MAAM,SAAS,GAAG,IAAI,EAAE,SAAS,CAAA;wBACjC,IAAI,CAAC,SAAS,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC;4BAAE,SAAQ;wBAC/D,IAAI,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC;4BAAE,SAAQ;wBAC3C,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;wBAC7B,MAAM,OAAO,GAAG,MAAM,SAAS,EAAE,CAAA;wBACjC,UAAU,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;wBACvC,SAAQ;oBACV,CAAC;oBAED,8DAA8D;oBAC9D,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;wBACxC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAyC,CAAA;wBAC5D,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAA;wBAC1D,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC;4BAAE,SAAQ;wBACjD,IAAI,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;4BACjC,cAAc,CAAC,kBAAkB,CAAC,CAAA;wBACpC,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,qEAAqE;gBACrE,0EAA0E;gBAC1E,qEAAqE;gBACrE,IAAI,UAAU,CAAC,MAAM,CAAC,OAAO;oBAAE,OAAM;gBACrC,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;gBAC1E,OAAO,CAAC,IAAI,CAAC,mEAAmE,MAAM,EAAE,CAAC,CAAA;YAC3F,CAAC;QACH,CAAC,CAAC,EAAE,CAAA;QAEJ,OAAO,GAAG,EAAE;YACV,UAAU,CAAC,KAAK,EAAE,CAAA;YAClB,IAAI,WAAW;gBAAE,YAAY,CAAC,WAAW,CAAC,CAAA;YAC1C,KAAK,iBAAiB,CAAC,OAAO,EAAE,CAAA;YAChC,KAAK,gBAAgB,CAAC,OAAO,EAAE,CAAA;QACjC,CAAC,CAAA;IACH,CAAC;CACF,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode2-direnv",
3
- "version": "2026.0907.0",
3
+ "version": "2026.0908.0",
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
@@ -15,6 +15,11 @@ import { promisify } from "node:util"
15
15
  * - On plugin setup: load env once (awaited, so the first command is ready)
16
16
  * - On session.created: re-sync per new session (e.g. after `direnv allow`)
17
17
  * - On filesystem.changed for .envrc/flake.nix/flake.lock: debounced reload
18
+ * (NOTE: as of server beta-19151 the server declares but never emits
19
+ * filesystem.changed, so this trigger is dormant; use the direnv_reload
20
+ * tool until an fs watcher or server-side emission exists)
21
+ * - Exposes a `direnv_reload` tool so the agent can force a re-sync manually
22
+ * (e.g. after the user edits the flake in their own editor/terminal)
18
23
  * - Injects the latest direnv export into every spawned shell via the
19
24
  * `shell.create.before` hook (primary mechanism)
20
25
  * - Reconciles process.env as a fallback for other subprocesses (LSP, MCP) and
@@ -82,7 +87,7 @@ const POISON_VARS = ["shellHook", ...SCRIPT_VARS, "export PATH"]
82
87
  const VALID_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/
83
88
 
84
89
  /** fallback PATHs used when repairing a corrupted PATH */
85
- const sanePath = () => {
90
+ export const sanePath = () => {
86
91
  const parts: string[] = []
87
92
  if (process.env.HOST_PATH) parts.push(process.env.HOST_PATH)
88
93
  if (process.env.HOME) parts.push(`${process.env.HOME}/.nix-profile/bin`)
@@ -99,7 +104,7 @@ const sanePath = () => {
99
104
 
100
105
  /** candidate locations for direnv, absolute paths first so that a PATH
101
106
  * corruption after setup cannot break the cached resolution */
102
- const direnvCandidates = () =>
107
+ export const direnvCandidates = () =>
103
108
  [
104
109
  `/etc/profiles/per-user/${process.env.USER ?? ""}/bin/direnv`,
105
110
  `${process.env.HOME ?? ""}/.nix-profile/bin/direnv`,
@@ -111,7 +116,7 @@ const direnvCandidates = () =>
111
116
  .concat("direnv")
112
117
 
113
118
  /** Strip known poison from process.env; returns the removed keys. */
114
- const stripPoison = (): string[] => {
119
+ export const stripPoison = (): string[] => {
115
120
  const removed: string[] = []
116
121
  for (const key of POISON_VARS) {
117
122
  if (key in process.env) {
@@ -122,12 +127,27 @@ const stripPoison = (): string[] => {
122
127
  return removed
123
128
  }
124
129
 
130
+ /**
131
+ * 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
+ * and no script-valued vars (drops nix's `shellHook` and friends).
134
+ */
135
+ export const filterVars = (vars: Record<string, string | null | undefined>): Record<string, string> => {
136
+ const safe: Record<string, string> = {}
137
+ for (const [key, value] of Object.entries(vars)) {
138
+ if (value == null) continue
139
+ if (!VALID_NAME.test(key) || SCRIPT_VARS.has(key)) continue
140
+ safe[key] = value
141
+ }
142
+ return safe
143
+ }
144
+
125
145
  /**
126
146
  * Repair process.env.PATH if it is corrupted (contains a literal `$`),
127
147
  * returning the usable PATH. A corrupted PATH otherwise makes direnv (and
128
148
  * every other subprocess this plugin could help) unlaunchable.
129
149
  */
130
- const repairPath = (): string => {
150
+ export const repairPath = (): string => {
131
151
  const current = process.env.PATH
132
152
  if (current && !current.includes("$")) return current
133
153
  const fallback = sanePath()
@@ -136,23 +156,47 @@ const repairPath = (): string => {
136
156
  return fallback
137
157
  }
138
158
 
139
- /** Resolve direnv once; prefers absolute locations, falls back to PATH. */
140
- let direnvPath: string | null | undefined
141
- const findDirenv = async (): Promise<string | null> => {
142
- if (direnvPath !== undefined) return direnvPath
143
- for (const candidate of direnvCandidates()) {
159
+ /**
160
+ * Return the first direnv candidate that responds to `direnv version`, or
161
+ * null. Pure w.r.t. module state so it stays testable.
162
+ */
163
+ export const probeDirenv = async (
164
+ candidates: string[],
165
+ exec: (file: string, args: string[]) => Promise<unknown> = (file, args) => run(file, args, { encoding: "utf8" })
166
+ ): Promise<string | null> => {
167
+ for (const candidate of candidates) {
144
168
  try {
145
- await run(candidate, ["version"], { encoding: "utf8" })
146
- direnvPath = candidate
147
- return direnvPath
169
+ await exec(candidate, ["version"])
170
+ return candidate
148
171
  } catch {
149
172
  // try next candidate
150
173
  }
151
174
  }
152
- direnvPath = null
175
+ return null
176
+ }
177
+
178
+ /** Resolve direnv once; prefers absolute locations, falls back to PATH. */
179
+ let direnvPath: string | null | undefined
180
+ const findDirenv = async (): Promise<string | null> => {
181
+ if (direnvPath !== undefined) return direnvPath
182
+ direnvPath = await probeDirenv(direnvCandidates())
153
183
  return direnvPath
154
184
  }
155
185
 
186
+ /** Find the nearest .envrc at or above `start`, not looking past `stopAt`. */
187
+ export const nearestEnvrc = (start: string, stopAt: string | null): string | null => {
188
+ let current = start
189
+ const boundary = stopAt || "/"
190
+ for (;;) {
191
+ const candidate = join(current, ".envrc")
192
+ if (existsSync(candidate)) return candidate
193
+ if (current === boundary || current === "/") return null
194
+ const parent = dirname(current)
195
+ if (parent === current) return null
196
+ current = parent
197
+ }
198
+ }
199
+
156
200
  /**
157
201
  * Strip poison and repair PATH. Runs before every direnv invocation so a
158
202
  * daemon that gets corrupted mid-flight heals itself on the next reload.
@@ -224,29 +268,7 @@ export default Plugin.define({
224
268
  const findEnvrc = async (
225
269
  startDir: string,
226
270
  stopAt: string | null
227
- ): Promise<string | null> => {
228
- let current = startDir
229
- const boundary = stopAt || "/"
230
-
231
- while (true) {
232
- if (existsSync(join(current, ".envrc"))) {
233
- return join(current, ".envrc")
234
- }
235
-
236
- if (current === boundary || current === "/") {
237
- break
238
- }
239
-
240
- const parent = dirname(current)
241
- if (parent === current) {
242
- break
243
- }
244
-
245
- current = parent
246
- }
247
-
248
- return null
249
- }
271
+ ): Promise<string | null> => nearestEnvrc(startDir, stopAt)
250
272
 
251
273
  /**
252
274
  * Resolve (and cache) the directory containing .envrc.
@@ -333,13 +355,11 @@ export default Plugin.define({
333
355
  }
334
356
 
335
357
  // 2. Apply current vars, counting additions and value changes.
336
- // Skip invalid names (e.g. a phantom `export PATH` entry) and
337
- // script-valued vars (e.g. nix's `shellHook`) — they corrupt
338
- // subprocess environments instead of configuring them.
358
+ // filterVars drops invalid names (e.g. a phantom `export PATH`
359
+ // entry) and script-valued vars (e.g. nix's `shellHook`) — they
360
+ // corrupt subprocess environments instead of configuring them.
339
361
  const nextApplied = new Set<string>()
340
- for (const [key, value] of Object.entries(newVars)) {
341
- if (value == null) continue
342
- if (!VALID_NAME.test(key) || SCRIPT_VARS.has(key)) continue
362
+ for (const [key, value] of Object.entries(filterVars(newVars))) {
343
363
  const current = process.env[key]
344
364
  if (current === undefined) outcome.added++
345
365
  else if (current !== value) outcome.changed++
@@ -409,6 +429,29 @@ export default Plugin.define({
409
429
  // Initial load: awaited so the first command of any session sees the env.
410
430
  logOutcome(await reloadEnv(), { initial: true })
411
431
 
432
+ /**
433
+ * Human/agent-readable one-liner for a reload outcome, used by the
434
+ * direnv_reload tool result.
435
+ */
436
+ const describeOutcome = (outcome: ReloadOutcome): string => {
437
+ if (outcome.blocked) {
438
+ return "direnv: .envrc is blocked. Run `direnv allow` and retry."
439
+ }
440
+ if (outcome.unavailable) {
441
+ return "direnv: unavailable (direnv not installed or no .envrc found)."
442
+ }
443
+ if (outcome.error) {
444
+ return "direnv: `direnv export json` failed; see server logs for details."
445
+ }
446
+ const parts: string[] = []
447
+ if (outcome.added) parts.push(`+${outcome.added}`)
448
+ if (outcome.changed) parts.push(`~${outcome.changed}`)
449
+ if (outcome.removed) parts.push(`-${outcome.removed}`)
450
+ return parts.length
451
+ ? `direnv: reloaded (${parts.join(" ")}); new shells use the updated environment.`
452
+ : "direnv: reloaded, nothing changed."
453
+ }
454
+
412
455
  // Primary mechanism: inject the latest direnv export into every shell the
413
456
  // server spawns for a working copy inside the devshell. The cached payload
414
457
  // keeps the hook synchronous and non-blocking.
@@ -420,6 +463,38 @@ export default Plugin.define({
420
463
  }
421
464
  })
422
465
 
466
+ /**
467
+ * Agent-facing manual reload. The filesystem.changed event the background
468
+ * reload depends on is declared but not emitted by current OpenCode 2
469
+ * servers, so after the user edits .envrc/flake.nix in their own editor
470
+ * the environment would silently go stale. This tool lets the agent force
471
+ * a re-sync on demand (works regardless of server-side event support).
472
+ */
473
+ const toolRegistration = await ctx.tool.transform((editor) => {
474
+ editor.namespace({
475
+ name: "direnv",
476
+ description: "Devshell (direnv) environment tools",
477
+ })
478
+ editor.add({
479
+ name: "reload",
480
+ description:
481
+ "Re-export the direnv devshell and apply it to OpenCode, so subsequently spawned shells " +
482
+ "see the updated environment. Call this after .envrc, flake.nix, or flake.lock were changed " +
483
+ "outside OpenCode (user edited them mid-session), or when devshell-provided tools are missing " +
484
+ "from PATH / resolve to stale /nix/store paths.",
485
+ input: {
486
+ type: "object",
487
+ properties: {},
488
+ additionalProperties: false,
489
+ },
490
+ execute: async () => {
491
+ const outcome = await reloadEnv()
492
+ logOutcome(outcome, { initial: false })
493
+ return { content: describeOutcome(outcome) }
494
+ },
495
+ })
496
+ })
497
+
423
498
  const isRelevantLocation = (location: EncodedEvent["location"]) =>
424
499
  !location?.directory || location.directory === directory
425
500
 
@@ -454,8 +529,13 @@ export default Plugin.define({
454
529
  }
455
530
  }
456
531
  }
457
- } catch {
458
- // stream aborted on cleanup or failed; nothing to do
532
+ } catch (error) {
533
+ // Abort is the normal cleanup path (controller aborted in teardown);
534
+ // anything else means we silently lost session.created/filesystem.changed
535
+ // triggers and the environment will go stale without anyone knowing.
536
+ if (controller.signal.aborted) return
537
+ const detail = error instanceof Error ? `${error.message}` : String(error)
538
+ console.warn(`direnv: event stream failed, devshell reload triggers are dead: ${detail}`)
459
539
  }
460
540
  })()
461
541
 
@@ -463,6 +543,7 @@ export default Plugin.define({
463
543
  controller.abort()
464
544
  if (reloadTimer) clearTimeout(reloadTimer)
465
545
  void shellRegistration.dispose()
546
+ void toolRegistration.dispose()
466
547
  }
467
548
  },
468
549
  })