agent-sh 0.12.14 → 0.12.15

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.
@@ -1,7 +1,30 @@
1
+ import { spawnSync } from "node:child_process";
1
2
  import { executeArgv, killSession } from "../../executor.js";
2
- // Targets PowerShell 7+ (`pwsh`). Legacy `powershell.exe` is intentionally
3
- // not auto-fallback its tool surface diverges enough that compatibility
4
- // shims aren't worth the maintenance.
3
+ let cachedPwshPath;
4
+ /** Resolve a usable PowerShell binary, or null if none is on PATH.
5
+ * Prefers PowerShell 7+ (`pwsh`), falls back to Windows PowerShell (`powershell`). */
6
+ function findPwsh() {
7
+ if (cachedPwshPath !== undefined)
8
+ return cachedPwshPath;
9
+ // Prefer PowerShell 7 (pwsh)
10
+ const pwsh = spawnSync("where", ["pwsh"], { encoding: "utf-8" });
11
+ if (pwsh.status === 0) {
12
+ cachedPwshPath = pwsh.stdout.split(/\r?\n/)[0].trim() || null;
13
+ if (cachedPwshPath)
14
+ return cachedPwshPath;
15
+ }
16
+ // Fallback to Windows PowerShell (powershell.exe)
17
+ const ps = spawnSync("where", ["powershell"], { encoding: "utf-8" });
18
+ cachedPwshPath = ps.status === 0 ? ps.stdout.split(/\r?\n/)[0].trim() || null : null;
19
+ return cachedPwshPath;
20
+ }
21
+ /** Return the PowerShell executable name for display purposes. */
22
+ function getPwshDisplayName() {
23
+ const path = findPwsh();
24
+ if (!path)
25
+ return "PowerShell";
26
+ return path.toLowerCase().includes("pwsh") ? "pwsh" : "powershell";
27
+ }
5
28
  export function createPwshTool(opts) {
6
29
  return {
7
30
  name: "pwsh",
@@ -54,8 +77,16 @@ export function createPwshTool(opts) {
54
77
  isError: false,
55
78
  };
56
79
  }
80
+ const pwshPath = findPwsh();
81
+ if (!pwshPath) {
82
+ return {
83
+ content: "PowerShell not found on PATH. Neither pwsh (PowerShell 7+) nor powershell (Windows PowerShell) is available.",
84
+ exitCode: 1,
85
+ isError: true,
86
+ };
87
+ }
57
88
  const { session, done } = executeArgv({
58
- file: "pwsh",
89
+ file: pwshPath,
59
90
  args: ["-NoProfile", "-NonInteractive", "-Command", command],
60
91
  cwd: opts.getCwd(),
61
92
  env: opts.getEnv(),
@@ -72,7 +103,7 @@ export function createPwshTool(opts) {
72
103
  }
73
104
  if (session.spawnFailed) {
74
105
  return {
75
- content: "PowerShell (pwsh) not found on PATH. Install PowerShell 7: winget install Microsoft.PowerShell.",
106
+ content: `${getPwshDisplayName()} not found on PATH. Install PowerShell 7: winget install Microsoft.PowerShell.`,
76
107
  exitCode: 1,
77
108
  isError: true,
78
109
  };
package/dist/executor.js CHANGED
@@ -53,7 +53,8 @@ export function executeCommand(opts) {
53
53
  stdio: ["ignore", "pipe", "pipe"],
54
54
  cwd: opts.cwd,
55
55
  env,
56
- detached: true,
56
+ detached: process.platform !== "win32",
57
+ windowsHide: true,
57
58
  });
58
59
  }
59
60
  catch (err) {
@@ -214,12 +215,14 @@ export function killSession(session) {
214
215
  if (!proc || !proc.pid)
215
216
  return () => { };
216
217
  // Try process-group kill first (works for executeCommand's detached bash
217
- // children); fall back to direct kill (executeArgv's non-detached spawn,
218
- // and Windows where negative pids aren't supported).
219
- try {
220
- process.kill(-proc.pid, "SIGTERM");
218
+ // children on Unix); fall back to direct kill (executeArgv's non-detached
219
+ // spawn, and Windows where negative pids aren't supported).
220
+ if (process.platform !== "win32") {
221
+ try {
222
+ process.kill(-proc.pid, "SIGTERM");
223
+ }
224
+ catch { }
221
225
  }
222
- catch { }
223
226
  try {
224
227
  proc.kill("SIGTERM");
225
228
  }
@@ -227,10 +230,12 @@ export function killSession(session) {
227
230
  let settled = false;
228
231
  const fallback = setTimeout(() => {
229
232
  if (!settled && !session.done && proc.pid) {
230
- try {
231
- process.kill(-proc.pid, "SIGKILL");
233
+ if (process.platform !== "win32") {
234
+ try {
235
+ process.kill(-proc.pid, "SIGKILL");
236
+ }
237
+ catch { }
232
238
  }
233
- catch { }
234
239
  try {
235
240
  proc.kill("SIGKILL");
236
241
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-sh",
3
- "version": "0.12.14",
3
+ "version": "0.12.15",
4
4
  "description": "A shell-first terminal where AI is one keystroke away",
5
5
  "type": "module",
6
6
  "main": "dist/core.js",