agent-nuvira 3.3.7 → 3.3.9

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.
Files changed (257) hide show
  1. package/README.md +57 -50
  2. package/dist/agents/agents/planner.d.ts.map +1 -1
  3. package/dist/agents/agents/planner.js +41 -0
  4. package/dist/agents/agents/planner.js.map +1 -1
  5. package/dist/agents/agents/reasoner.d.ts.map +1 -1
  6. package/dist/agents/agents/reasoner.js +6 -0
  7. package/dist/agents/agents/reasoner.js.map +1 -1
  8. package/dist/agents/agents/runner.d.ts +6 -0
  9. package/dist/agents/agents/runner.d.ts.map +1 -1
  10. package/dist/agents/agents/runner.js +82 -5
  11. package/dist/agents/agents/runner.js.map +1 -1
  12. package/dist/agents/agents/writer-tool-calling.d.ts.map +1 -1
  13. package/dist/agents/agents/writer-tool-calling.js +5 -2
  14. package/dist/agents/agents/writer-tool-calling.js.map +1 -1
  15. package/dist/agents/agents/writer.d.ts.map +1 -1
  16. package/dist/agents/agents/writer.js +8 -4
  17. package/dist/agents/agents/writer.js.map +1 -1
  18. package/dist/agents/fanout-scheduler.d.ts +72 -0
  19. package/dist/agents/fanout-scheduler.d.ts.map +1 -0
  20. package/dist/agents/fanout-scheduler.js +100 -0
  21. package/dist/agents/fanout-scheduler.js.map +1 -0
  22. package/dist/agents/orchestrator.d.ts.map +1 -1
  23. package/dist/agents/orchestrator.js +30 -1
  24. package/dist/agents/orchestrator.js.map +1 -1
  25. package/dist/agents/plan-quality.d.ts +58 -0
  26. package/dist/agents/plan-quality.d.ts.map +1 -0
  27. package/dist/agents/plan-quality.js +152 -0
  28. package/dist/agents/plan-quality.js.map +1 -0
  29. package/dist/agents/prompt-assembly.d.ts +8 -0
  30. package/dist/agents/prompt-assembly.d.ts.map +1 -1
  31. package/dist/agents/prompt-assembly.js +18 -0
  32. package/dist/agents/prompt-assembly.js.map +1 -1
  33. package/dist/agents/step-handoff.d.ts +12 -2
  34. package/dist/agents/step-handoff.d.ts.map +1 -1
  35. package/dist/agents/step-handoff.js +65 -8
  36. package/dist/agents/step-handoff.js.map +1 -1
  37. package/dist/agents/tool-calling-agent.d.ts.map +1 -1
  38. package/dist/agents/tool-calling-agent.js +18 -0
  39. package/dist/agents/tool-calling-agent.js.map +1 -1
  40. package/dist/cli/cache.d.ts.map +1 -1
  41. package/dist/cli/cache.js +34 -4
  42. package/dist/cli/cache.js.map +1 -1
  43. package/dist/cli/chat.d.ts +6 -0
  44. package/dist/cli/chat.d.ts.map +1 -1
  45. package/dist/cli/chat.js +79 -18
  46. package/dist/cli/chat.js.map +1 -1
  47. package/dist/cli/cli-program.d.ts.map +1 -1
  48. package/dist/cli/cli-program.js +6 -0
  49. package/dist/cli/cli-program.js.map +1 -1
  50. package/dist/cli/config.d.ts +10 -0
  51. package/dist/cli/config.d.ts.map +1 -1
  52. package/dist/cli/config.js +179 -1
  53. package/dist/cli/config.js.map +1 -1
  54. package/dist/cli/continuity.d.ts +61 -0
  55. package/dist/cli/continuity.d.ts.map +1 -0
  56. package/dist/cli/continuity.js +112 -0
  57. package/dist/cli/continuity.js.map +1 -0
  58. package/dist/cli/dashboard.d.ts +3 -1
  59. package/dist/cli/dashboard.d.ts.map +1 -1
  60. package/dist/cli/dashboard.js +5 -16
  61. package/dist/cli/dashboard.js.map +1 -1
  62. package/dist/cli/doctor.d.ts.map +1 -1
  63. package/dist/cli/doctor.js +48 -1
  64. package/dist/cli/doctor.js.map +1 -1
  65. package/dist/cli/execute.d.ts +8 -0
  66. package/dist/cli/execute.d.ts.map +1 -1
  67. package/dist/cli/execute.js +34 -1
  68. package/dist/cli/execute.js.map +1 -1
  69. package/dist/cli/loop-executor.d.ts +24 -0
  70. package/dist/cli/loop-executor.d.ts.map +1 -1
  71. package/dist/cli/loop-executor.js +134 -13
  72. package/dist/cli/loop-executor.js.map +1 -1
  73. package/dist/cli/website.d.ts +25 -0
  74. package/dist/cli/website.d.ts.map +1 -0
  75. package/dist/cli/website.js +58 -0
  76. package/dist/cli/website.js.map +1 -0
  77. package/dist/config/manager.d.ts.map +1 -1
  78. package/dist/config/manager.js +35 -0
  79. package/dist/config/manager.js.map +1 -1
  80. package/dist/config/process-env.d.ts.map +1 -1
  81. package/dist/config/process-env.js +20 -0
  82. package/dist/config/process-env.js.map +1 -1
  83. package/dist/config/provider-env.d.ts +2 -1
  84. package/dist/config/provider-env.d.ts.map +1 -1
  85. package/dist/config/provider-env.js +19 -2
  86. package/dist/config/provider-env.js.map +1 -1
  87. package/dist/config/service-catalog.d.ts +81 -0
  88. package/dist/config/service-catalog.d.ts.map +1 -0
  89. package/dist/config/service-catalog.js +286 -0
  90. package/dist/config/service-catalog.js.map +1 -0
  91. package/dist/config/service-probe.d.ts +27 -0
  92. package/dist/config/service-probe.d.ts.map +1 -0
  93. package/dist/config/service-probe.js +104 -0
  94. package/dist/config/service-probe.js.map +1 -0
  95. package/dist/config/types.d.ts +63 -0
  96. package/dist/config/types.d.ts.map +1 -1
  97. package/dist/context/cache.d.ts +46 -2
  98. package/dist/context/cache.d.ts.map +1 -1
  99. package/dist/context/cache.js +85 -7
  100. package/dist/context/cache.js.map +1 -1
  101. package/dist/findings/verdicts.d.ts +59 -0
  102. package/dist/findings/verdicts.d.ts.map +1 -1
  103. package/dist/findings/verdicts.js +117 -0
  104. package/dist/findings/verdicts.js.map +1 -1
  105. package/dist/forwarded.d.ts +2 -0
  106. package/dist/forwarded.d.ts.map +1 -0
  107. package/dist/forwarded.js +2 -0
  108. package/dist/forwarded.js.map +1 -0
  109. package/dist/gateway/registry.d.ts.map +1 -1
  110. package/dist/gateway/registry.js +9 -0
  111. package/dist/gateway/registry.js.map +1 -1
  112. package/dist/learning/auto-router.d.ts +30 -0
  113. package/dist/learning/auto-router.d.ts.map +1 -1
  114. package/dist/learning/auto-router.js +69 -12
  115. package/dist/learning/auto-router.js.map +1 -1
  116. package/dist/learning/context-assembly.d.ts +37 -0
  117. package/dist/learning/context-assembly.d.ts.map +1 -0
  118. package/dist/learning/context-assembly.js +63 -0
  119. package/dist/learning/context-assembly.js.map +1 -0
  120. package/dist/learning/reasoning-trace.d.ts +26 -5
  121. package/dist/learning/reasoning-trace.d.ts.map +1 -1
  122. package/dist/learning/reasoning-trace.js +21 -1
  123. package/dist/learning/reasoning-trace.js.map +1 -1
  124. package/dist/learning/session-digest.d.ts +78 -0
  125. package/dist/learning/session-digest.d.ts.map +1 -0
  126. package/dist/learning/session-digest.js +185 -0
  127. package/dist/learning/session-digest.js.map +1 -0
  128. package/dist/learning/session-recall.d.ts +135 -0
  129. package/dist/learning/session-recall.d.ts.map +1 -0
  130. package/dist/learning/session-recall.js +305 -0
  131. package/dist/learning/session-recall.js.map +1 -0
  132. package/dist/learning/session-store.d.ts +172 -0
  133. package/dist/learning/session-store.d.ts.map +1 -0
  134. package/dist/learning/session-store.js +424 -0
  135. package/dist/learning/session-store.js.map +1 -0
  136. package/dist/learning/step-checkpoint.d.ts +28 -0
  137. package/dist/learning/step-checkpoint.d.ts.map +1 -1
  138. package/dist/learning/step-checkpoint.js +90 -6
  139. package/dist/learning/step-checkpoint.js.map +1 -1
  140. package/dist/learning/working-state.d.ts +19 -0
  141. package/dist/learning/working-state.d.ts.map +1 -1
  142. package/dist/learning/working-state.js +34 -1
  143. package/dist/learning/working-state.js.map +1 -1
  144. package/dist/parity/drivers.d.ts.map +1 -1
  145. package/dist/parity/drivers.js +29 -0
  146. package/dist/parity/drivers.js.map +1 -1
  147. package/dist/parity/wire-fixtures.d.ts +88 -0
  148. package/dist/parity/wire-fixtures.d.ts.map +1 -0
  149. package/dist/parity/wire-fixtures.js +405 -0
  150. package/dist/parity/wire-fixtures.js.map +1 -0
  151. package/dist/tools/artifact-append.d.ts +23 -0
  152. package/dist/tools/artifact-append.d.ts.map +1 -1
  153. package/dist/tools/artifact-append.js +28 -0
  154. package/dist/tools/artifact-append.js.map +1 -1
  155. package/dist/tools/ask-user.d.ts +5 -0
  156. package/dist/tools/ask-user.d.ts.map +1 -1
  157. package/dist/tools/ask-user.js +51 -5
  158. package/dist/tools/ask-user.js.map +1 -1
  159. package/dist/tools/child-agent-entry.js +1 -0
  160. package/dist/tools/child-agent-entry.js.map +1 -1
  161. package/dist/tools/child-agent-runtime.d.ts +7 -0
  162. package/dist/tools/child-agent-runtime.d.ts.map +1 -1
  163. package/dist/tools/child-agent-runtime.js +116 -6
  164. package/dist/tools/child-agent-runtime.js.map +1 -1
  165. package/dist/tools/child-agent-worker.d.ts +15 -0
  166. package/dist/tools/child-agent-worker.d.ts.map +1 -0
  167. package/dist/tools/child-agent-worker.js.map +1 -0
  168. package/dist/tools/coding-tools.d.ts.map +1 -1
  169. package/dist/tools/coding-tools.js +11 -0
  170. package/dist/tools/coding-tools.js.map +1 -1
  171. package/dist/tools/finding-tool.d.ts +6 -1
  172. package/dist/tools/finding-tool.d.ts.map +1 -1
  173. package/dist/tools/finding-tool.js +15 -2
  174. package/dist/tools/finding-tool.js.map +1 -1
  175. package/dist/tools/followup-utils.d.ts +35 -0
  176. package/dist/tools/followup-utils.d.ts.map +1 -1
  177. package/dist/tools/followup-utils.js +36 -0
  178. package/dist/tools/followup-utils.js.map +1 -1
  179. package/dist/tools/loop-project-context.d.ts +4 -1
  180. package/dist/tools/loop-project-context.d.ts.map +1 -1
  181. package/dist/tools/loop-project-context.js +48 -1
  182. package/dist/tools/loop-project-context.js.map +1 -1
  183. package/dist/tools/loop-skill-hint.d.ts.map +1 -1
  184. package/dist/tools/loop-skill-hint.js +7 -0
  185. package/dist/tools/loop-skill-hint.js.map +1 -1
  186. package/dist/tools/modality/image-gen.d.ts +25 -6
  187. package/dist/tools/modality/image-gen.d.ts.map +1 -1
  188. package/dist/tools/modality/image-gen.js +46 -27
  189. package/dist/tools/modality/image-gen.js.map +1 -1
  190. package/dist/tools/modality/image-providers.d.ts +71 -0
  191. package/dist/tools/modality/image-providers.d.ts.map +1 -0
  192. package/dist/tools/modality/image-providers.js +277 -0
  193. package/dist/tools/modality/image-providers.js.map +1 -0
  194. package/dist/tools/registry.d.ts +10 -1
  195. package/dist/tools/registry.d.ts.map +1 -1
  196. package/dist/tools/registry.js +35 -8
  197. package/dist/tools/registry.js.map +1 -1
  198. package/dist/tools/run-cli.d.ts.map +1 -1
  199. package/dist/tools/run-cli.js +39 -1
  200. package/dist/tools/run-cli.js.map +1 -1
  201. package/dist/tools/run-terminal.d.ts.map +1 -1
  202. package/dist/tools/run-terminal.js +50 -6
  203. package/dist/tools/run-terminal.js.map +1 -1
  204. package/dist/tools/subagent-spawner.d.ts +8 -0
  205. package/dist/tools/subagent-spawner.d.ts.map +1 -1
  206. package/dist/tools/subagent-spawner.js +3 -0
  207. package/dist/tools/subagent-spawner.js.map +1 -1
  208. package/dist/tools/tool-loop.d.ts +55 -0
  209. package/dist/tools/tool-loop.d.ts.map +1 -1
  210. package/dist/tools/tool-loop.js +136 -0
  211. package/dist/tools/tool-loop.js.map +1 -1
  212. package/dist/tools/untrusted-content.d.ts +29 -0
  213. package/dist/tools/untrusted-content.d.ts.map +1 -0
  214. package/dist/tools/untrusted-content.js +53 -0
  215. package/dist/tools/untrusted-content.js.map +1 -0
  216. package/dist/tools/web-research.d.ts +76 -14
  217. package/dist/tools/web-research.d.ts.map +1 -1
  218. package/dist/tools/web-research.js +280 -35
  219. package/dist/tools/web-research.js.map +1 -1
  220. package/dist/utils/effect-verification.d.ts +115 -0
  221. package/dist/utils/effect-verification.d.ts.map +1 -0
  222. package/dist/utils/effect-verification.js +337 -0
  223. package/dist/utils/effect-verification.js.map +1 -0
  224. package/dist/utils/open-url.d.ts +16 -0
  225. package/dist/utils/open-url.d.ts.map +1 -0
  226. package/dist/utils/open-url.js +32 -0
  227. package/dist/utils/open-url.js.map +1 -0
  228. package/dist/utils/project-env.d.ts +146 -0
  229. package/dist/utils/project-env.d.ts.map +1 -0
  230. package/dist/utils/project-env.js +584 -0
  231. package/dist/utils/project-env.js.map +1 -0
  232. package/dist/utils/shell.d.ts +7 -0
  233. package/dist/utils/shell.d.ts.map +1 -1
  234. package/dist/utils/shell.js +2 -0
  235. package/dist/utils/shell.js.map +1 -1
  236. package/dist/web-dashboard/chat-console.d.ts +2 -0
  237. package/dist/web-dashboard/chat-console.d.ts.map +1 -1
  238. package/dist/web-dashboard/chat-console.js +7 -0
  239. package/dist/web-dashboard/chat-console.js.map +1 -1
  240. package/dist/web-dashboard/server.d.ts +3 -1
  241. package/dist/web-dashboard/server.d.ts.map +1 -1
  242. package/dist/web-dashboard/server.js +534 -8
  243. package/dist/web-dashboard/server.js.map +1 -1
  244. package/dist/web-dashboard/src/types.d.ts +150 -1
  245. package/dist/web-dashboard/src/types.d.ts.map +1 -1
  246. package/dist/web-dashboard/workspace-guard.d.ts +40 -0
  247. package/dist/web-dashboard/workspace-guard.d.ts.map +1 -0
  248. package/dist/web-dashboard/workspace-guard.js +92 -0
  249. package/dist/web-dashboard/workspace-guard.js.map +1 -0
  250. package/package.json +4 -1
  251. package/src/web-dashboard/public/assets/index-Beportyl.js +207 -0
  252. package/src/web-dashboard/public/assets/index-Beportyl.js.map +1 -0
  253. package/src/web-dashboard/public/assets/index-gtQyg9nm.css +1 -0
  254. package/src/web-dashboard/public/index.html +2 -2
  255. package/src/web-dashboard/public/assets/index-D1YFCcIZ.js +0 -207
  256. package/src/web-dashboard/public/assets/index-D1YFCcIZ.js.map +0 -1
  257. package/src/web-dashboard/public/assets/index-jkW5qcf-.css +0 -1
@@ -0,0 +1,584 @@
1
+ /**
2
+ * Project interpreter canonicalization + pre-run environment guard.
3
+ *
4
+ * WHY THIS EXISTS (the live Aukat_check failure):
5
+ * One chat session built a macOS app by running `python3 -m venv venv` and
6
+ * `pip install …` against the SYSTEM interpreter, while a project virtualenv sat
7
+ * in the same directory. A later rebuild therefore used an interpreter that did
8
+ * not have the project's own dependencies, produced an app that crashed with
9
+ * `ModuleNotFoundError: No module named 'PyQt6'`, and the run still reported
10
+ * success. The root cause was not a missing dependency — it was that NOTHING
11
+ * pinned "which interpreter is this project's" for the run, so each command
12
+ * guessed and the guesses disagreed.
13
+ *
14
+ * This module makes the guess unnecessary, deterministically and LLM-free:
15
+ *
16
+ * 1. DISCOVER — find the project's virtualenv (`.venv` preferred, then
17
+ * `venv`/`env`), walking up a bounded number of parent directories.
18
+ * 2. PIN — remember it for the whole process (keyed by directory), so every
19
+ * command in the run sees the SAME interpreter.
20
+ * 3. APPLY — prepend its `bin/` to PATH and set `VIRTUAL_ENV`, so a bare
21
+ * `python`/`pip`/`pyinstaller` resolves to the project env.
22
+ * 4. GUARD — refuse the two mistakes that caused the failure: installing
23
+ * Python packages into an interpreter OUTSIDE the project venv, and
24
+ * building/running with an interpreter that LACKS the project's declared
25
+ * dependencies.
26
+ *
27
+ * All checks are best-effort: a probe failure reports, it never breaks a run.
28
+ * `NUVIRA_ENV_GUARD=off` disables the refusals (the escape hatch a deployment
29
+ * with a deliberate system-Python setup needs).
30
+ */
31
+ import { spawnSync } from 'node:child_process';
32
+ import { existsSync, readFileSync, statSync } from 'node:fs';
33
+ import { delimiter, dirname, join, resolve } from 'node:path';
34
+ /** Where the project marker files that describe Python deps live. */
35
+ const PYTHON_MANIFESTS = [
36
+ 'requirements.txt',
37
+ 'pyproject.toml',
38
+ 'setup.py',
39
+ 'setup.cfg',
40
+ 'Pipfile',
41
+ 'Pipfile.lock',
42
+ 'poetry.lock',
43
+ ];
44
+ /** Names that appear in a dependency manifest but are not distributions. */
45
+ const NON_DISTRIBUTION_NAMES = new Set([
46
+ 'python',
47
+ 'python_version',
48
+ 'python_full_version',
49
+ 'requires-python',
50
+ 'requires_python',
51
+ ]);
52
+ /**
53
+ * Candidate virtualenv directory names, in PREFERENCE order. `.venv` first
54
+ * because it is the modern convention (and the one a tool should create), and
55
+ * a project that has drifted into two envs should converge on one.
56
+ */
57
+ const VENV_DIR_NAMES = ['.venv', 'venv', 'env', '.virtualenv', 'virtualenv'];
58
+ /** How many parent directories to search for a project venv. */
59
+ const MAX_PARENT_SEARCH = 3;
60
+ /** Is `dir` a Python virtualenv directory? */
61
+ function isVenvDir(dir) {
62
+ try {
63
+ if (!existsSync(dir) || !statSync(dir).isDirectory())
64
+ return false;
65
+ // Python 3 venvs carry pyvenv.cfg; older/edge cases still have an activate script.
66
+ if (existsSync(join(dir, 'pyvenv.cfg')))
67
+ return true;
68
+ return (existsSync(join(dir, 'bin', 'activate')) ||
69
+ existsSync(join(dir, 'Scripts', 'activate.bat')));
70
+ }
71
+ catch {
72
+ return false;
73
+ }
74
+ }
75
+ /** The interpreter path inside a venv dir, or null when none is present. */
76
+ function interpreterIn(dir, binDir) {
77
+ const candidates = binDir === 'Scripts'
78
+ ? [join(dir, 'Scripts', 'python.exe')]
79
+ : [join(dir, 'bin', 'python'), join(dir, 'bin', 'python3')];
80
+ for (const p of candidates) {
81
+ if (existsSync(p))
82
+ return p;
83
+ }
84
+ return null;
85
+ }
86
+ /**
87
+ * Find the project's virtualenv, starting at `startDir` and walking up a
88
+ * bounded number of parents (nearest wins, so a monorepo package's own env
89
+ * beats the repo root's).
90
+ */
91
+ export function findProjectVenv(startDir) {
92
+ let dir;
93
+ try {
94
+ dir = resolve(startDir);
95
+ }
96
+ catch {
97
+ return null;
98
+ }
99
+ for (let depth = 0; depth <= MAX_PARENT_SEARCH; depth++) {
100
+ for (const name of VENV_DIR_NAMES) {
101
+ const candidate = join(dir, name);
102
+ if (!isVenvDir(candidate))
103
+ continue;
104
+ const binDir = existsSync(join(candidate, 'Scripts')) ? 'Scripts' : 'bin';
105
+ const python = interpreterIn(candidate, binDir);
106
+ if (python)
107
+ return { dir: candidate, python, binDir: join(candidate, binDir) };
108
+ }
109
+ const parent = dirname(dir);
110
+ if (parent === dir)
111
+ break;
112
+ dir = parent;
113
+ }
114
+ return null;
115
+ }
116
+ /**
117
+ * The pinned interpreter per directory, for the lifetime of the process.
118
+ *
119
+ * "Pin it for the whole run" is the whole point: without this, two commands in
120
+ * the same turn can resolve different interpreters (which is exactly how one
121
+ * session created `venv` and then built with `.venv`). Keyed by the directory
122
+ * the command runs in, so different projects in one process stay separate.
123
+ */
124
+ const PINNED = new Map();
125
+ /** The project venv for `dir`, discovered once and reused for the run. */
126
+ export function getPinnedProjectVenv(dir) {
127
+ let key;
128
+ try {
129
+ key = resolve(dir);
130
+ }
131
+ catch {
132
+ return null;
133
+ }
134
+ if (PINNED.has(key))
135
+ return PINNED.get(key) ?? null;
136
+ const found = findProjectVenv(key);
137
+ PINNED.set(key, found);
138
+ return found;
139
+ }
140
+ /** Forget pinned interpreters (tests; also after creating a venv mid-run). */
141
+ export function clearPinnedProjectVenv() {
142
+ PINNED.clear();
143
+ }
144
+ /** Name of the venv the sandbox creates when a project has none. */
145
+ export const SANDBOX_VENV_NAME = '.venv';
146
+ /**
147
+ * Provision a project-scoped virtualenv (`C3` install sandbox).
148
+ *
149
+ * The live failure's 4th finding: a project-scoped fix mutated the machine's
150
+ * GLOBAL Python. Refusing such installs protects the machine but blocks the
151
+ * work; the better answer is to give the install a sandbox to land in. When no
152
+ * project venv exists, create `.venv` from the interpreter on PATH, PIN it for
153
+ * the run, and hand it back — so the following `pip install` populates the
154
+ * project env and the global interpreter is never touched.
155
+ *
156
+ * Returns null when the venv cannot be created (no base interpreter, or venv
157
+ * creation failed) — the caller then refuses rather than falling back to a
158
+ * global install.
159
+ */
160
+ export function ensureProjectVenv(dir) {
161
+ const existing = getPinnedProjectVenv(dir);
162
+ if (existing)
163
+ return existing;
164
+ const base = interpreterOnPath();
165
+ if (!base)
166
+ return null;
167
+ let key;
168
+ try {
169
+ key = resolve(dir);
170
+ }
171
+ catch {
172
+ return null;
173
+ }
174
+ const venvDir = join(key, SANDBOX_VENV_NAME);
175
+ try {
176
+ const res = spawnSync(base, ['-m', 'venv', venvDir], {
177
+ encoding: 'utf-8',
178
+ timeout: 120_000,
179
+ windowsHide: true,
180
+ });
181
+ if (res.error || res.status !== 0)
182
+ return null;
183
+ }
184
+ catch {
185
+ return null;
186
+ }
187
+ const venv = findProjectVenv(key);
188
+ if (!venv || !venv.python)
189
+ return null;
190
+ PINNED.set(key, venv);
191
+ return venv;
192
+ }
193
+ /**
194
+ * Apply the pinned interpreter to a command's environment: prepend its `bin/`
195
+ * to PATH and set `VIRTUAL_ENV`, so a bare `python`/`pip`/`pyinstaller`
196
+ * resolves to the project env instead of whatever the shell would have found.
197
+ * A no-op when there is no venv (the environment is returned unchanged).
198
+ */
199
+ export function applyProjectEnvironment(env, venv) {
200
+ if (!venv)
201
+ return env;
202
+ const current = env.PATH ?? '';
203
+ // A venv already on PATH is left alone; otherwise it goes first so it wins.
204
+ const parts = current.split(delimiter).filter(Boolean);
205
+ if (!parts.includes(venv.binDir))
206
+ parts.unshift(venv.binDir);
207
+ return {
208
+ ...env,
209
+ PATH: parts.join(delimiter),
210
+ VIRTUAL_ENV: venv.dir,
211
+ // A VIRTUAL_ENV without a matching interpreter can confuse sub-tools.
212
+ PYTHONHOME: undefined,
213
+ };
214
+ }
215
+ /**
216
+ * Parse the distribution names a project declares in `requirements.txt`.
217
+ *
218
+ * Deliberately narrow and text-based (no TOML/pip dependency): it keeps only
219
+ * the name before any version specifier or environment marker, skips flags
220
+ * (`-r`, `-e`, `--index-url`), comments and blank lines, and follows a `-r`
221
+ * include one level deep. A name it cannot read is skipped rather than
222
+ * guessed — the guard must never invent a requirement the project did not ask
223
+ * for.
224
+ */
225
+ function requirementNamesFromRequirementsTxt(text) {
226
+ const names = [];
227
+ for (const raw of text.split(/\r?\n/)) {
228
+ const line = raw.trim();
229
+ if (!line || line.startsWith('#') || line.startsWith('-'))
230
+ continue;
231
+ // `pkg[extra]==1.2 ; python_version>'3.8'` -> `pkg`
232
+ const match = line.match(/^([A-Za-z0-9][A-Za-z0-9._-]*)/);
233
+ if (match)
234
+ names.push(match[1]);
235
+ }
236
+ return names;
237
+ }
238
+ /**
239
+ * Distribution names declared as KEYS of one or more TOML tables, selected by
240
+ * a section predicate. Handles the `[tool.poetry.dependencies]` shape
241
+ * (`requests = "^2.31"` / `requests = { version = "…" }`) and poetry's newer
242
+ * `[tool.poetry.group.<name>.dependencies]` tables. A key that names the
243
+ * interpreter (`python`) or an environment selector is skipped — it is not a
244
+ * distribution the guard should demand.
245
+ *
246
+ * Text-based on purpose: the guard must not pull a TOML parser into the hot
247
+ * path, and an unreadable line is skipped rather than guessed.
248
+ */
249
+ function requirementNamesFromTomlSections(text, isDependencySection) {
250
+ const names = [];
251
+ let inSection = false;
252
+ for (const raw of text.split(/\r?\n/)) {
253
+ const line = raw.trim();
254
+ const section = line.match(/^\[([^\]]+)\]/);
255
+ if (section) {
256
+ inSection = isDependencySection(section[1].trim());
257
+ continue;
258
+ }
259
+ if (!inSection || !line || line.startsWith('#'))
260
+ continue;
261
+ const match = line.match(/^([A-Za-z0-9][A-Za-z0-9._-]*)\s*=/);
262
+ if (match && !NON_DISTRIBUTION_NAMES.has(match[1].toLowerCase()))
263
+ names.push(match[1]);
264
+ }
265
+ return names;
266
+ }
267
+ /** Is this a poetry dependency table? (`tool.poetry.dependencies`, dev, groups) */
268
+ function isPoetryDependencySection(section) {
269
+ return (section === 'tool.poetry.dependencies' ||
270
+ section === 'tool.poetry.dev-dependencies' ||
271
+ /^tool\.poetry\.group\.[^.]+\.dependencies$/.test(section));
272
+ }
273
+ /** Is this a pipenv table? (`packages`, `dev-packages`) */
274
+ function isPipfileDependencySection(section) {
275
+ return section === 'packages' || section === 'dev-packages';
276
+ }
277
+ /**
278
+ * Distribution names from a `Pipfile` (`[packages]` + `[dev-packages]`).
279
+ */
280
+ function requirementNamesFromPipfile(text) {
281
+ const names = [];
282
+ let inSection = false;
283
+ for (const raw of text.split(/\r?\n/)) {
284
+ const line = raw.trim();
285
+ const section = line.match(/^\[([^\]]+)\]/);
286
+ if (section) {
287
+ inSection = isPipfileDependencySection(section[1].trim());
288
+ continue;
289
+ }
290
+ if (!inSection || !line || line.startsWith('#'))
291
+ continue;
292
+ const match = line.match(/^([A-Za-z0-9][A-Za-z0-9._-]*)\s*=/);
293
+ if (match && !NON_DISTRIBUTION_NAMES.has(match[1].toLowerCase()))
294
+ names.push(match[1]);
295
+ }
296
+ return names;
297
+ }
298
+ /**
299
+ * Distribution names from a `Pipfile.lock` (JSON): the `default` and
300
+ * `develop` maps. Used only as a fallback when no `Pipfile` is present.
301
+ */
302
+ function requirementNamesFromPipfileLock(text) {
303
+ const names = [];
304
+ try {
305
+ const parsed = JSON.parse(text);
306
+ for (const key of ['default', 'develop']) {
307
+ const group = parsed[key];
308
+ if (group && typeof group === 'object')
309
+ names.push(...Object.keys(group));
310
+ }
311
+ }
312
+ catch {
313
+ /* best-effort */
314
+ }
315
+ return names;
316
+ }
317
+ /**
318
+ * The distribution names a project declares, from `requirements.txt`, a
319
+ * best-effort scan of `pyproject.toml` (PEP 621 `dependencies = [ … ]` AND
320
+ * poetry's `[tool.poetry.dependencies]` tables), and a `Pipfile`/`Pipfile.lock`
321
+ * (pipenv). Returns [] when there is nothing to check — the guard then does
322
+ * nothing.
323
+ */
324
+ export function projectRequirementNames(projectDir) {
325
+ const names = new Set();
326
+ const reqPath = join(projectDir, 'requirements.txt');
327
+ try {
328
+ if (existsSync(reqPath)) {
329
+ for (const n of requirementNamesFromRequirementsTxt(readFileSync(reqPath, 'utf-8'))) {
330
+ names.add(n);
331
+ }
332
+ }
333
+ }
334
+ catch {
335
+ /* best-effort */
336
+ }
337
+ const pyproject = join(projectDir, 'pyproject.toml');
338
+ try {
339
+ if (existsSync(pyproject)) {
340
+ const text = readFileSync(pyproject, 'utf-8');
341
+ // PEP 621 / poetry 2.x: `dependencies = [ "a", "b" ]`
342
+ const block = text.match(/dependencies\s*=\s*\[([\s\S]*?)\]/);
343
+ if (block) {
344
+ for (const n of requirementNamesFromRequirementsTxt(block[1].replace(/["',]/g, '\n'))) {
345
+ names.add(n);
346
+ }
347
+ }
348
+ // poetry 1.x: `[tool.poetry.dependencies]` / groups / dev-dependencies
349
+ for (const n of requirementNamesFromTomlSections(text, isPoetryDependencySection)) {
350
+ names.add(n);
351
+ }
352
+ }
353
+ }
354
+ catch {
355
+ /* best-effort */
356
+ }
357
+ const pipfile = join(projectDir, 'Pipfile');
358
+ try {
359
+ if (existsSync(pipfile)) {
360
+ for (const n of requirementNamesFromPipfile(readFileSync(pipfile, 'utf-8')))
361
+ names.add(n);
362
+ }
363
+ else {
364
+ const lock = join(projectDir, 'Pipfile.lock');
365
+ if (existsSync(lock)) {
366
+ for (const n of requirementNamesFromPipfileLock(readFileSync(lock, 'utf-8')))
367
+ names.add(n);
368
+ }
369
+ }
370
+ }
371
+ catch {
372
+ /* best-effort */
373
+ }
374
+ return [...names];
375
+ }
376
+ /** Does this directory look like it declares Python dependencies? */
377
+ export function hasPythonManifest(dir) {
378
+ return PYTHON_MANIFESTS.some((m) => existsSync(join(dir, m)));
379
+ }
380
+ // ─── Command classification ────────────────────────────────────────────────
381
+ /** Split a shell line into the separately-run pieces (the `&&`/`;`/`|` chain). */
382
+ function commandSegments(command) {
383
+ return command
384
+ .toLowerCase()
385
+ .split(/&&|;|\|\||\n|\|/)
386
+ .map((s) => s.trim())
387
+ .filter(Boolean);
388
+ }
389
+ const PYTHON_TOOLCHAIN_RE = /^(?:(?:sudo|env|command|time)\s+)*(?:[\w./-]*\/)?(python3?(?:\.\d+)?|pip3?|uv|pyinstaller|pytest|py\.test|uvicorn|gunicorn|flask|django-admin|poetry|pipenv|tox)\b/;
390
+ /**
391
+ * Does any segment of this command invoke the Python toolchain? (A bare
392
+ * `python`/`pip`/`pyinstaller`/`pytest`, or `python -m …`.)
393
+ */
394
+ export function isPythonToolchainCommand(command) {
395
+ return commandSegments(command).some((s) => PYTHON_TOOLCHAIN_RE.test(s));
396
+ }
397
+ const PIP_INSTALL_RE = /^(?:(?:sudo|env|command|time)\s+)*(?:[\w./-]*\/)?(?:pip3?\s+install|python3?(?:\.\d+)?\s+-m\s+pip\s+install|uv\s+(?:pip\s+)?install|uv\s+add|poetry\s+(?:add|install)|pipenv\s+install)\b/;
398
+ /** Does any segment of this command install Python packages? */
399
+ export function isPythonInstallCommand(command) {
400
+ return commandSegments(command).some((s) => PIP_INSTALL_RE.test(s));
401
+ }
402
+ /**
403
+ * Does the command name an absolute interpreter OUTSIDE the pinned venv
404
+ * (e.g. `/usr/local/bin/python3 -m pip install …`)? A bare `python3` does NOT
405
+ * count: with the venv on PATH it resolves to the project env, which is the
406
+ * outcome we want.
407
+ */
408
+ export function targetsForeignInterpreter(command, venv) {
409
+ // `--user` installs into the user site, never the project env — foreign
410
+ // whether or not an absolute interpreter is also named.
411
+ if (/(?:^|\s)--user\b/.test(command))
412
+ return true;
413
+ const abs = command.match(/(?:^|\s)(\/[\w./-]*\/?(?:python3?(?:\.\d+)?|pip3?))\b/g) ?? [];
414
+ if (abs.length === 0)
415
+ return false;
416
+ if (!venv)
417
+ return true; // an absolute interpreter with no pinned venv is foreign by definition
418
+ return abs.some((token) => {
419
+ const path = token.trim();
420
+ return !path.startsWith(venv.binDir) && !path.startsWith(venv.dir);
421
+ });
422
+ }
423
+ /** Install packages the project declares, inside the given interpreter. */
424
+ const PROBE_SCRIPT = [
425
+ 'import sys, json, importlib.metadata as md',
426
+ 'reqs = json.loads(sys.argv[1])',
427
+ 'missing = []',
428
+ 'for r in reqs:',
429
+ ' ok = False',
430
+ " for c in (r, r.replace('_','-'), r.replace('.','-')):",
431
+ ' try:',
432
+ ' md.version(c); ok = True; break',
433
+ ' except Exception:',
434
+ ' pass',
435
+ ' if not ok:',
436
+ ' missing.append(r)',
437
+ 'print(json.dumps(missing))',
438
+ ].join('\n');
439
+ /**
440
+ * Which declared distributions are NOT installed in `python`?
441
+ * A probe that fails to run returns [] — an unavailable interpreter is not
442
+ * evidence that a dependency is missing, and the guard must never refuse on a
443
+ * guess.
444
+ */
445
+ export const defaultEnvironmentProbe = (python, names) => {
446
+ if (names.length === 0)
447
+ return [];
448
+ try {
449
+ const res = spawnSync(python, ['-c', PROBE_SCRIPT, JSON.stringify(names)], {
450
+ encoding: 'utf-8',
451
+ timeout: 8000,
452
+ windowsHide: true,
453
+ });
454
+ if (res.error || res.status !== 0)
455
+ return [];
456
+ const parsed = JSON.parse((res.stdout ?? '').trim() || '[]');
457
+ return Array.isArray(parsed) ? parsed.map(String) : [];
458
+ }
459
+ catch {
460
+ return [];
461
+ }
462
+ };
463
+ /** Memoize probes for the run, keyed by interpreter + the requirement set. */
464
+ const PROBE_CACHE = new Map();
465
+ /** The interpreter a bare `python`/`python3` would resolve to on PATH. */
466
+ function interpreterOnPath() {
467
+ try {
468
+ const res = spawnSync(process.platform === 'win32' ? 'where' : 'which', ['python3'], {
469
+ encoding: 'utf-8',
470
+ timeout: 4000,
471
+ windowsHide: true,
472
+ });
473
+ if (res.status !== 0)
474
+ return null;
475
+ const first = (res.stdout ?? '').split(/\r?\n/).map((s) => s.trim()).filter(Boolean)[0];
476
+ return first ?? null;
477
+ }
478
+ catch {
479
+ return null;
480
+ }
481
+ }
482
+ /** Is the guard disabled by the deployment? */
483
+ export function envGuardDisabled() {
484
+ const raw = (process.env.NUVIRA_ENV_GUARD ?? process.env.BUFF_ENV_GUARD ?? '').trim().toLowerCase();
485
+ return raw === 'off' || raw === '0' || raw === 'false' || raw === 'no';
486
+ }
487
+ /**
488
+ * Decide whether a command may run against the project's environment.
489
+ *
490
+ * Two refusals, both drawn from the live failure:
491
+ * 1. a Python PACKAGE INSTALL that would land outside the project venv (or
492
+ * with no venv at all while the project declares dependencies);
493
+ * 2. a BUILD/RUN with an interpreter that is missing the project's declared
494
+ * dependencies — the `PyQt6` case, caught before the build instead of
495
+ * after a successful-looking bundle.
496
+ * Everything else proceeds, with the pinned venv applied to the environment.
497
+ */
498
+ export function guardCommandEnvironment(command, cwd, options = {}) {
499
+ if (envGuardDisabled())
500
+ return { action: 'not-applicable' };
501
+ if (!isPythonToolchainCommand(command))
502
+ return { action: 'not-applicable' };
503
+ let venv = getPinnedProjectVenv(cwd);
504
+ const names = projectRequirementNames(cwd);
505
+ if (isPythonInstallCommand(command)) {
506
+ if (targetsForeignInterpreter(command, venv)) {
507
+ return {
508
+ action: 'refuse',
509
+ reason: 'this install names an interpreter outside the project virtualenv',
510
+ hint: venv
511
+ ? `Install into the project env instead: \`${venv.python} -m pip install …\` (or rely on the pinned PATH, which already points at ${venv.binDir}).`
512
+ : 'Create and use a project virtualenv first: `python3 -m venv .venv` then `.venv/bin/python -m pip install …` — never install project dependencies into the system interpreter.',
513
+ };
514
+ }
515
+ // ── C3: install sandbox ───────────────────────────────────────────────
516
+ // With no project venv, a `pip install` would mutate the interpreter on
517
+ // PATH — the machine's GLOBAL Python. Rather than merely refuse (which
518
+ // blocks the fix), provision a project-scoped `.venv`, PIN it, and run the
519
+ // install there. Only a provision failure falls back to refusal, so the
520
+ // global interpreter is never the target.
521
+ if (!venv) {
522
+ const provision = options.provision ?? ensureProjectVenv;
523
+ venv = provision(cwd);
524
+ if (!venv) {
525
+ return {
526
+ action: 'refuse',
527
+ reason: names.length > 0
528
+ ? 'this project declares Python dependencies but has no virtualenv, and one could not be created, so the install would mutate the system interpreter'
529
+ : 'this install has no project virtualenv to land in, and one could not be created, so it would mutate the system interpreter',
530
+ hint: 'Create and use one yourself: `python3 -m venv .venv && .venv/bin/python -m pip install …` (this pins `.venv` for the rest of the run).',
531
+ };
532
+ }
533
+ return {
534
+ action: 'proceed',
535
+ venv,
536
+ note: `created a project venv ${venv.dir} and sandboxed the install there (the system interpreter is untouched)`,
537
+ };
538
+ }
539
+ return { action: 'proceed', venv, note: `installing into the project venv ${venv.dir}` };
540
+ }
541
+ // Build/run: the interpreter must actually have the project's dependencies.
542
+ const interpreter = venv?.python ?? interpreterOnPath();
543
+ if (interpreter && names.length > 0) {
544
+ const probe = options.probe ?? defaultEnvironmentProbe;
545
+ const cacheKey = `${interpreter}\u0000${names.join(',')}`;
546
+ let missing = PROBE_CACHE.get(cacheKey);
547
+ if (missing === undefined) {
548
+ missing = probe(interpreter, names);
549
+ PROBE_CACHE.set(cacheKey, missing);
550
+ }
551
+ if (missing.length > 0) {
552
+ const label = venv ? 'the project venv' : 'the interpreter on PATH';
553
+ return {
554
+ action: 'refuse',
555
+ reason: `${label} (${interpreter}) is missing ${missing.length} declared dependency(ies): ${missing.join(', ')}`,
556
+ hint: venv
557
+ ? `Install them into the venv first: \`${venv.python} -m pip install -r requirements.txt\`, then re-run this command.`
558
+ : 'Create a project venv (`python3 -m venv .venv`), install the requirements into it, then re-run.',
559
+ };
560
+ }
561
+ }
562
+ return { action: 'proceed', venv, note: venv ? `using the project venv ${venv.dir}` : undefined };
563
+ }
564
+ /** Forget memoized probes (tests; also after an install changes the env). */
565
+ export function clearEnvironmentProbeCache() {
566
+ PROBE_CACHE.clear();
567
+ }
568
+ /**
569
+ * A one-line description of the project interpreter for the ambient project
570
+ * context, so the model USES the pinned env instead of re-deriving it. '' when
571
+ * the directory declares nothing Python.
572
+ */
573
+ export function describeProjectInterpreter(dir) {
574
+ try {
575
+ const venv = getPinnedProjectVenv(dir);
576
+ if (!venv)
577
+ return hasPythonManifest(dir) ? 'python: no project venv found (create `.venv`)' : '';
578
+ return `python: ${venv.python} (pinned for this project)`;
579
+ }
580
+ catch {
581
+ return '';
582
+ }
583
+ }
584
+ //# sourceMappingURL=project-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-env.js","sourceRoot":"","sources":["../../src/utils/project-env.ts"],"names":[],"mappings":"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"}
@@ -59,6 +59,13 @@ export interface RunShellOptions {
59
59
  emitEvents?: boolean;
60
60
  /** Source label for emitted events (default: 'shell'). */
61
61
  source?: string;
62
+ /**
63
+ * Environment overrides merged OVER the inherited process environment
64
+ * (execa's default `extendEnv`). Used to apply a project's pinned virtualenv
65
+ * (PATH/VIRTUAL_ENV) to every subprocess the pipeline runner spawns, so a
66
+ * bare `python`/`pip` resolves to the project env. See project-env.ts.
67
+ */
68
+ env?: Record<string, string | undefined>;
62
69
  }
63
70
  /** Result of a `runShell` / `runShellSync` call. */
64
71
  export interface RunShellResult {
@@ -1 +1 @@
1
- {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAQH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAID,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,sEAAsE;IACtE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,oDAAoD;AACpD,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,OAAO,EAAE,OAAO,CAAC;IACjB,qDAAqD;IACrD,QAAQ,EAAE,OAAO,CAAC;IAClB,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;IACjB,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAYD;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAyEtG;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,cAAc,CAsD3F"}
1
+ {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAQH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAID,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,sEAAsE;IACtE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC1C;AAED,oDAAoD;AACpD,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,OAAO,EAAE,OAAO,CAAC;IACjB,qDAAqD;IACrD,QAAQ,EAAE,OAAO,CAAC;IAClB,yDAAyD;IACzD,OAAO,EAAE,OAAO,CAAC;IACjB,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAYD;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CA0EtG;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,cAAc,CAuD3F"}
@@ -83,6 +83,7 @@ export async function runShell(command, options = {}) {
83
83
  reject: false,
84
84
  signal: options.signal,
85
85
  windowsHide: true,
86
+ ...(options.env ? { env: options.env } : {}),
86
87
  });
87
88
  if (options.onChunk && subprocess.all) {
88
89
  subprocess.all.on('data', (chunk) => {
@@ -149,6 +150,7 @@ export function runShellSync(command, options = {}) {
149
150
  all: true,
150
151
  reject: false,
151
152
  windowsHide: true,
153
+ ...(options.env ? { env: options.env } : {}),
152
154
  });
153
155
  stdout = result.stdout ?? '';
154
156
  stderr = result.stderr ?? '';